[英]Singleton in Objective C (Non-ARC)
我發現了如何在目標c(Non-ARC)中實現單例。
// AppTools.h in my code
@interface AppTools : NSObject {
NSString *className;
}
@property ( nonatomic, retain ) NSString *className;
+ ( id ) sharedInstance;
@end // AppTools
// AppTools.m in my code
static AppTools *sharedAppToolsInstance = nil;
@implementation AppTools
@synthesize className;
- ( id ) init {
self = [ super init ];
if ( self ) {
className = [ [ NSString alloc ] initWithString: @"AppTools" ];
}
return self;
} // init
- ( void ) dealloc {
// Should never be called, but just here for clarity really.
[ className release ];
[ super dealloc ];
} // dealloc
+ ( id ) sharedInstance {
@synchronized( self ) {
if ( sharedAppToolsInstance == nil )
sharedAppToolsInstance = [ [ super allocWithZone: NULL ] init ];
}
return sharedAppToolsInstance;
} // sharedInstance
+ ( id ) allocWithZone: ( NSZone * )zone {
return [ [ self sharedInstance ] retain ];
} // allocWithZone:
- ( id ) copyWithZone: ( NSZone * )zone {
return self;
} // copyWithZone:
- ( id ) retain {
return self;
} // retain
- ( unsigned int ) retainCount {
return UINT_MAX; // denotes an object that cannot be released
} // retainCount
- ( oneway void ) release {
// never release
} // release
- ( id ) autorelease {
return self;
} // autorelease
我想知道如何在sharedInstance方法中使用allocWithZone:。 在此,allocWithZone:方法的接收者為“ super”,“ super”為NSObject。 盡管返回值是NSObject實例,但它被替換為sharedInstance。
那么className的存儲空間在哪里? 我不知道如何處理這部分代碼。
預先感謝。
我認為您發布的代碼很難用於創建單例。
在我的所有項目中,我都使用以下代碼來使用單例。 它非常簡單,線程安全並且可以完美運行:
+ (CustomClass *)shared
{
static CustomClass *singleton = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
singleton = [[CustomClass alloc] init];
});
return singleton;
}
而且我相信您可以在ARC和非ARC項目中使用它。
更新:如注釋中所述,它實際上是shared object
而不是singleton
因為可以創建更多特定類的實例。 但這已經足夠接近了。
我認為,如果您不是在編寫開源代碼/庫,而沒有其他人會使用它,那么使用共享庫並將它們視為單例可能會容易得多。
我使用與Nekto相同的代碼,但singleton = [[CustomClass alloc] init];
應該是singleton = [[self alloc] init];
。
想象一個子類CustomSubclass
。 如果你打電話
CustomSubclass *sharedObject = [CustomSubclass shared];
您將不會獲得CustomSubclass
而是CustomClass
。
您問“那么className的存儲空間在哪里?”
大多數類本身並不實現alloc
或allocWithZone
,而是依賴於從NSObject
繼承的實現。 NSObject
實現分配原始調用類的對象。
因此,在您的示例AppTools
確實覆蓋了allocWithZone
,此實現通過對super
的調用來調用NSObject
的allocWithZone
,而NSObject
的方法執行實際分配並返回AppTools
類型的對象。
[注意:如果您想知道NSObject
的實現如何知道要分配哪種對象,那么這很簡單-調用繼承的方法不會更改方法的self
參數, alloc
/ allocWithZone
是類方法,而self
參數是類方法本身引用類對象(而不是類的實例對象)。]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.