Singleton目标c澄清

当我继续学习时,这本书实施了一个单身人士。 我理解使用它的原因,但我只想对代码做一些澄清。

+ (BNRItemStore *)defaultStore { static BNRItemStore *defaultStore = nil; if(!defaultStore) defaultStore = [[super allocWithZone:nil] init]; return defaultStore; } 

在行static BNRItemStore * defaultStore = nil; 直到退货声明。 我的问题是; 我一直称这个类为[[BNRItemStore defaultStore] someMethod]; 在另一个类或应用程序的一部分中,defaultStore变量将设置为nil?

干杯

重要的是要理解static关键字有两个效果。 一个是它在调用方法之前使该变量存在,并在返回之后保持不变,以便它可用于下一次调用。 另一个影响更微妙 – 初始化静态变量的“赋值”在加载代码时执行,而不是在调用方法时执行。 所以它不会在每次通话时重新初始化。

但由于变量存在于方法的“外部”,因此它的名称应该是唯一的 – 不要在此类或另一个单独的另一个单例中使用相同的名称。

这是具有静态存储持续时间的变量的初始化器。 将可执行文件加载到内存时将设置该值。

请注意,由于具有静态存储持续时间的所有变量都自动设置为0,因此无需将值显式设置为nil。

对于函数 – 静态变量的行

 static BNRItemStore *defaultStore = nil; 

不是任务 。 相反,它是静态初始化 ,它只发生一次 – 代码第一次通过你的函数。 在后续调用中,值不会为nil ,因为您为其指定了非零值。

您的实现在单线程环境中是安全的。 对于并发环境,您需要添加某种forms的同步。

静态变量仅在首次调用函数/方法时初始化。 在那之后,你基本上可以假装线路不存在。

Apple推荐如下内容

 + (BNRItemStore *)defaultStore { static BNRItemStore *defaultStore = nil; static dispatch_once_t done; dispatch_once(&done, ^{ defaultStore = [BNRItemStore alloc]init];}); return defaultStore; } 

上面的代码假定ARC – 如果不使用ARC,则必须定义不执行任何保留,释放,自动释放和dealloc方法。