【发布时间】:2014-02-02 02:09:21
【问题描述】:
Matt Galloway 建议这是初始化单例的正确方法:
+ (id)sharedManager {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
我已经测试过,它可以正常工作,但我不明白为什么。首次创建单例时,变量 sharedMyManager 设置为 init 行的内容,但是当已经创建单例并且我使用 [MySingleton sharedManager]; 访问它时,代码的第一行运行,将 sharedMyManager 设置为 @987654327 @ 然后最后一行运行返回理论上 nil 的内容。事实上,它返回的是正确的单例,但为什么呢?
如果 nil 设置为 nil,sharedMyManager 如何返回正确的对象?
注意,因为在创建单例之后,我正在与sharedManager 的后续调用交谈。
我想 static 关键字正在发挥作用,现在允许多次分配值,但如果这是真的,那么 init 部分不应该工作,因为静态变量首先被分配给 nil .
请解释一下,因为我才五岁。谢谢。
【问题讨论】:
-
你怎么知道 sharedMyManager 被设置为 nil (在第一次之后)?也许它只是进入静态声明,意识到 sharedMyManager 存在并继续运行......就在“return sharedMyManager”运行之前,它的值是什么?
-
提示:何时
dispatch_once运行提供给它的块?该块在运行时会立即对静态变量产生副作用(并且保证运行一次[通过dispatch_once和静态onceTokensentinel],并且仅在从该方法第一次返回之前运行一次)。 -
就“魔术”
static修饰符而言:它有效地使变量成为持久的全局变量 - 只能从该方法上下文访问。这种static变量的初始化发生在在方法被调用之前。如果你要写static MyManager *sharedMyManager; sharedMyManager = nil;那么赋值 - 不是初始化! - 每次都会发生。 -
@user2864740 - 我说的是对该方法的后续调用,而不是第一次。
标签: ios objective-c cocoa-touch singleton