以下是示例代码的链接http://developer.apple.com/library/ios/#samplecode/MVCNetworking/Introduction/Intro.html
以下是NetworkManager.m文件中的代码段
+ (NetworkManager *)sharedManager
// See comment in header.
{
static NetworkManager * sNetworkManager;
// This can be called on any thread, so we synchronise. We only do this in
// the sNetworkManager case because, once sNetworkManager goes non-nil, it can
// never go nil again.
if (sNetworkManager == nil) {
@synchronized (self) {
sNetworkManager = [[NetworkManager alloc] init];
assert(sNetworkManager != nil);
}
}
return sNetworkManager;
}
Run Code Online (Sandbox Code Playgroud)
显然这里存在线程安全问题.当存在多个线程时,可以创建两个NetworkManager实例.所以Apple犯了一个错误,对吗?
是的,这是错误的。sNetworkManager从as开始nil,考虑两个线程 T1 和 T2。
一种可能的情况(如果不太可能的话)是:
T1: Determines (sNetworkManager == nil) is true
T2: Determines (sNetworkManager == nil) is true
T1: Takes the @synchronized lock
Creates a NetworkManager
Sets sNetworkManager
Releases the lock
T2: Takes the @synchronized lock
Creates a NetworkManager
Sets sNetworkManager, LEAKING the first one
Releases the lock
Run Code Online (Sandbox Code Playgroud)
这个问题有一些更安全的方法。
| 归档时间: |
|
| 查看次数: |
1317 次 |
| 最近记录: |