簡體   English   中英

目標C中的單例(非ARC)

[英]Singleton in Objective C (Non-ARC)

我發現了如何在目標c(Non-ARC)中實現單例。

馬特·加洛韋(Matt Galloway)的單身人士

// 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的存儲空間在哪里?”

大多數類本身並不實現allocallocWithZone ,而是依賴於從NSObject繼承的實現。 NSObject實現分配原始調用類的對象。

因此,在您的示例AppTools確實覆蓋了allocWithZone ,此實現通過對super的調用來調用NSObjectallocWithZone ,而NSObject的方法執行實際分配並返回AppTools類型的對象。

[注意:如果您想知道NSObject的實現如何知道要分配哪種對象,那么這很簡單-調用繼承的方法不會更改方法的self參數, alloc / allocWithZone是類方法,而self參數是類方法本身引用類對象(而不是類的實例對象)。]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM