【问题标题】:How to dealloc and re-initialize a singleton class?如何解除分配并重新初始化单例类?
【发布时间】:2011-06-28 06:38:11
【问题描述】:

是否可以释放类对象?

我有一个单例类“singleton.h”,它有一个实例,我们可以在任何其他视图控制器中使用它的属性。

+(singleton *)sharedMethod{
static singleton *myInstance=nil;
if(myInstance ==nil){
myInstance=[[singleton alloc] init]; myInstace.str=@"hello";
}
return myInstance;
}

我想知道的是..,有什么方法可以在我们的任何视图控制器中释放类对象...然后再次创建一个新的单例类的实例..,我试过这样做..,Xcode 抛出错误“无法释放类对象”。

【问题讨论】:

  • [[singleton sharedMethod] release]; [singleton sharedMethod] = nil; 然后[singleton sharedMethod] 会给你一个新的实例。编辑:很公平,也许那行不通。但是无论如何,解除单例的整个概念都是错误的。永远不应该这样做。
  • @darvids0n:不,[singleton sharedMethod] = nil; 甚至无法编译,因为您试图将右值分配给右值。此外,在真正的单例实现中,通过使 release 成为 NOP 来防止释放。
  • 可能是*[singleton sharedMethod] = nil;?还是= NULL/= 0x0;?
  • @darvids0n:不,仍然无法工作,即使它会编译(由于代码没有按照您的想法执行,所以稍后会出现警告和崩溃)。只有当您有一个方法可以返回您可以取消引用的 myInstance 变量的地址 时,它才会起作用。
  • 根据单例的定义,不能用新的实例替换单例,满足成为单例的要求。您无法控制谁可能隐藏了对旧实例的引用,鉴于单例的定义,这应该是完全有效的事情。

标签: iphone objective-c xcode


【解决方案1】:

单例的全部意义在于你永远不会释放它。其他类可能会保护指向实例的指针,因此如果您想替换它,有时会出现奇怪的行为甚至崩溃。所以你不应该这样做。

但这是可能的,只要您没有覆盖 releaseretainCount 方法。但是您引用的错误消息似乎表明您已经按照[MyClass release]; 的方式做了一些事情,当然这是行不通的。

顺便说一句,您似乎将 singleton 作为类名。请尽量遵守 Apple 使用的编码约定,以使您和其他人的生活更轻松。类名应始终以大写字符开头,方法名应始终以小写字符开头。

【讨论】:

  • 感谢您的回复..,我刚刚在 stackoverflow 中写下了该示例,以便它易于理解。,不用担心,我在我的代码中使用 Apple 约定。我知道创建单例类的目的是不通过应用程序释放它。只是想知道..,如果可能的话。
【解决方案2】:

声明

static YOUR_CLASS *shared = nil;
static dispatch_once_t oncePredicate; //very important for reinitialize.

使用实例

+ (instancetype)shared  {
    dispatch_once(&oncePredicate, ^{
        shared = [[self alloc] init];
    });
    return shared;
}

重置

+ (void)reset{
    @synchronized(self) {
        shared = nil;
        oncePredicate = 0;
    }
}

你很高兴 √

【讨论】:

    【解决方案3】:

    如果您不释放 singleton 类,这非常重要,因为在您的应用程序完全执行之前不建议这样做。有关更多信息,请参阅this。要重新初始化您的 singleton 类,您需要执行与第一次相同的操作。

    【讨论】:

      【解决方案4】:

      这个解决方案帮助了我。创建一个单独的方法来初始化类。

      @implementation SomeManager
      
      static id sharedManager = nil;
      
      + (void)initialize {
          if (self == [SomeManager class]) {
              sharedManager = [[self alloc] init];
          }
      }
      
      + (id)sharedManager {
          return sharedManager;
      }
      
      @end
      

      来源:http://eschatologist.net/blog/?p=178

      【讨论】:

        猜你喜欢
        • 2013-03-24
        • 1970-01-01
        • 1970-01-01
        • 2012-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多