問題描述
您好,我有一個用于單例的 iOS 以前版本的實現,如下所示:
Hi I had an implementation previous versions of iOS for a singleton as follows:
.h 文件
@interface CartSingleton : NSObject
{
}
+(CartSingleton *) getSingleton;
.m 文件
@implementation CartSingleton
static CartSingleton *sharedSingleton = nil;
+(CartSingleton *) getSingleton
{
if (sharedSingleton !=nil)
{
NSLog(@"Cart has already been created.....");
return sharedSingleton;
}
@synchronized(self)
{
if (sharedSingleton == nil)
{
sharedSingleton = [[self alloc]init];
NSLog(@"Created a new Cart");
}
}
return sharedSingleton;
}
//==============================================================================
+(id)alloc
{
@synchronized([CartSingleton class])
{
NSLog(@"inside alloc");
NSAssert(sharedSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
sharedSingleton = [super alloc];
return sharedSingleton;
}
return nil;
}
//==============================================================================
-(id)init
{
self = [super init];
}
然而,我在網上看到人們使用以下代碼實現了單例設計模式:
However on the web I see people have implemented the Singleton design pattern using this code:
+ (id)sharedInstance
{
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init]; // or some other init method
});
return _sharedObject;
}
請有經驗的人指導一下.我是一個新手,在單例的舊 iOS 實現和新的 iOS 實現之間完全混淆,哪個是正確的?
Could someone who is experience please guide me. Im a newbie and thoroughly confused between the old iOS implementation of the Singleton and the new one and which is the correct one?
非常感謝
推薦答案
嚴格來說,你必須使用:
Strictly speaking, you must use:
+ (MySingleton*) instance {
static dispatch_once_t _singletonPredicate;
static MySingleton *_singleton = nil;
dispatch_once(&_singletonPredicate, ^{
_singleton = [[super allocWithZone:nil] init];
});
return _singleton;
}
+ (id) allocWithZone:(NSZone *)zone {
return [self instance];
}
現在你保證不能調用 alloc/init 并創建另一個實例.
Now you guarantee that one cannot call alloc/init and create another instance.
說明:實例方法在類級別,是您獲取單例引用的主要訪問方法.該方法僅使用 dispatch_once() 內置隊列,該隊列只會執行一次塊.運行時如何保證塊只執行一次?使用您提供的謂詞(dispatch_once_t 類型).這種低級調用將保證即使有多個線程試圖調用它,也只有一個成功,其他的等到第一個完成后再返回.
Explanation: The instance method is at the class level and is your main access method to get a reference to the singleton. The method simply uses the dispatch_once() built-in queue that will only execute a block once. How does the runtime guarantee that the block is only executed once? Using the predicate you supply (of type dispatch_once_t). This low-level call will guarantee that even if there are multiple threads trying to call it, only one succeeds, the others wait until the first one is done and then returns.
我們重寫 allocWithZone 的原因是因為 alloc 調用 allocWithZone 傳遞 nil 作為區域(對于默認區域).為了防止流氓代碼分配和初始化另一個實例,我們重寫 allocWithZone 以便傳回的實例是已經初始化的單例.這可以防止創建第二個實例.
The reason we override allocWithZone is because alloc calls allocWithZone passing nil as the zone (for the default zone). To prevent rogue code from allocating and init-ializing another instance we override allocWithZone so that the instance passed back is the already initialized singleton. This prevents one from creating a second instance.
這篇關于iOS 5 中的單例?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!