【问题标题】:Thread Safe Singleton in iOS6iOS6 中的线程安全单例
【发布时间】:2013-02-03 01:32:17
【问题描述】:

我正在尝试获取线程安全的单例设计模式的更新版本。 Here 是我知道的一个版本。但是,我无法使其在 iOS6 中运行

这是我想要做的:

这是我的类方法

 +(id)getSingleton
 {
    static dispatch_once_t pred;
    static EntryContainerSingleton *entriesSingleton = nil;
    dispatch_once(&pred, ^{
        entriesSingleton = [[super alloc] init];

        });

    return entriesSingleton;   
   }

 +(id)alloc
 {
  @synchronized([EntryContainerSingleton class])
  {
      NSLog(@"inside alloc of EntryContainerSingleton");
   ERROR >>>>>  NSAssert(entriesSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
   ERROR >>>>>   entriesSingleton = [super alloc];
   ERROR >>>>>   return entriesSingleton;
   }
  return nil;
  }

  -(id)init
  {
     self = [super init];
     ......Some custom INitialization
     return self;
 }

此代码引发如上标记的错误。错误消息显示使用未声明的标识符。另外上面的链接推荐使用

  [[allocWithZone:nil] init] 

当我这样使用它时它会抱怨

  +(id)allocWithZone:(NSZone*)zone
 {
    return [self instance];
 }

经过数小时的努力使其发挥作用。如果有人能指出如何正确地做到这一点,那就太好了。我花了很多时间在谷歌上搜索,但没有找到完整的实现示例。

谢谢

【问题讨论】:

  • 看看this answer...它在iOS5和iOS6中也运行良好。
  • 请注意,在您绝对不能有两个实例的情况下,该问题的公认答案在某种程度上是合理的,即使尝试也会出错。这在 ObjC 中是非常罕见的情况。在几乎所有情况下,问题中的代码(不是答案)都是正确的。
  • @holex 谢谢,但您的链接指的是可能不是线程安全的实现。我正在寻找我在问题中提供的 GCD 代码 sn-p 的正确版本。
  • 这里的问题中给出了正确的版本,并解释了为什么它是正确的:stackoverflow.com/questions/9119042/…。你不应该覆盖alloc,除非你有非常非常强烈的理由这样做。
  • 也在这里:mikeash.com/pyblog/…

标签: ios objective-c design-patterns thread-safety singleton


【解决方案1】:

为什么不直接使用 +initialize?

static MyClass *gSingleton;

+(void) initialize {
  if ( self == [MyClass class] ) {
    gSingleton = [MyClass new];     
  }
}

+(MyClass*) getSingleton {
  return gSingleton;
}

它是线程安全的。唯一的问题是它不会阻止某人使用 alloc/init 或 new 分配第二个对象。

【讨论】:

  • 曾经有一段时间+initialize 对此很有用,但自从添加了dispatch_once() 之后,这是首选的方法。
  • 如果它没有坏,就不要修理它! :-)
  • @EricS 这可能不是线程安全的。我正在寻找类似于我提供的代码的 GCD 解决方案
  • dispatch_once 更具可读性。请注意,即使使用initialize,您也不应该调用方法“getSingleton”。 “得到”有特殊的含义。它应该是“sharedMyClass”
  • 顺便说一句,“更具可读性”是指它将所有相关代码放在一个地方,而不是将其分布在文件的三个不同部分(initialize 可能也在做其他事情,这使这种模式变得混乱)。
猜你喜欢
  • 2011-02-24
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多