2011-12-07 28 views
1

如何在Objective-C中使用本地靜態對象?如何在Objective-C中使用本地靜態對象?

- (void)foo { 
    static NSMutableArray *mutableArr = nil; 
    // initialize mutableArr somehow somewhere 
    // using mutableArr several times 
} 
+0

@KevinBallard是的,我覺得Objective-C的也許支持。 – Nickolas

+0

@KevinBallard在C中,你不需要關心引用計數。在這裏,我必須保持計數並在某個時候釋放它。我想知道是否有一個簡單的方法來做到這一點。 – Nickolas

+4

@Nickolas:靜態變量存在於程序的整個生命週期中。如果你希望對象具有普通對象的使用壽命,爲什麼使用靜態?我想我錯過了你所設想的用法。 – Chuck

回答

0

我希望我沒有錯過什麼,但這是我如何使用它:

- (void)foo { 
    static NSMutableArray *mutableArr = nil; 
    if (mutableArr == nil) { 
     mutableArr = [[NSMutableArray alloc] init...]; 
     // add more first time initialization as required 
    } 
    assert(mutableArr); 
    // now, use mutableArr freely... 
} 
+0

FWIW,這對於來自多個線程的併發訪問而言不是線程安全的。也就是說,如果您要將共享引用出售給單個可變數據結構,那麼您已經使該方法的所有不同調用者的作業都成爲線程安全的。 – ipmcc

0

if use static var。在初始化var之前檢查它是否被初始化是一種好方法。

5

如果你的目標很簡單,就是有一個單身,似乎對於這些共同的,公認的模式天如下:

#import <dispatch/dispatch.h> 

+ (NSMyObjectType*)sharedMyObject 
{ 
    static dispatch_once_t pred; 
    static NSMyObjectType* sValue; 
    dispatch_once(&pred, ^{ sValue = [[NSMyObjectType alloc] init]; }); 
    return sValue; 
} 

這將是從多個線程併發訪問的安全,對於泄漏NSMyObjectType的情況下,假設NSMyObjectType是不可改變的。還要注意的是,除非你有一個具體的理由不這樣做(例如,採用特定的@protocol),這是有道理的做出這樣的存取類的方法,而不是實例方法。這給了API消費者暗示這是共享資源(在方法名稱中使用shared這個詞)。

如果您爲多線程併發訪問而出售可變共享數據結構,那麼您需要使用一種本質上對此類用途安全的類型,或者您希望自己作爲API供應商提供這種安全性。舉例來說,如果你想爲販賣的的NSMutableSet,你可能會做這樣的事情:

@class NSFoo; 

@interface SharedFooVender : NSObject 

+ (NSSet*)sharedFoos; 
+ (void)addSharedFoo:(NSFoo*)foo; 
+ (void)removeSharedFoo:(NSFoo*)foo; 

@end 

@implementation SharedFooVender 

static NSMutableSet* pPrivateSharedMutableSetOfFoos() 
{ 
    static NSMutableSet* sSetOfFoos = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sSetOfFoos = [[NSMutableSet alloc] init]; 
    }); 
    return sSetOfFoos; 
} 

+ (NSSet*)sharedFoos 
{ 
    NSMutableSet* sharedFoos = pPrivateSharedMutableSetOfFoos(); 
    @synchronized(sharedFoos) 
    { 
     return [[sharedFoos copy] autorelease]; 
    }  
} 

+ (void)addSharedFoo:(NSFoo*)foo 
{ 
    if (nil == foo) return; 
    NSMutableSet* sharedFoos = pPrivateSharedMutableSetOfFoos(); 
    @synchronized(sharedFoos) 
    { 
     [sharedFoos addObject: foo]; 
    } 
} 

+ (void)removeSharedFoo:(NSFoo*)foo 
{ 
    if (nil == foo) return; 
    NSMutableSet* sharedFoos = pPrivateSharedMutableSetOfFoos(); 
    @synchronized(sharedFoos) 
    { 
     [sharedFoos removeObject: foo]; 
    } 
} 

@end 

通過同步實際的底層可變對象的訪問和變異,和自動售貨機整個設置爲不可變的副本,你提供安全從多個線程的併發訪問(但應當注意的是,通過使一成不變的副本,消費者可以掛在陳舊的拷貝,並在本質上,每一個不可改變的副本應認爲是從它的創建即時失效。)

FWIW,有100萬不同的方法這一點 - 我並不是說這種方法是完美的每一個(甚至任何情況下)。但依靠你的API的消費者爲你提供鎖定是一種災難。現在

,所有的說,接受的答案是好的,假設您只允許單線程訪問。如果你只希望這是從主線程(也許在UIKit的上下文中)使用時,可以使用公認的答案,雖然讓你失敗的早期,如果後來有人開始呼籲從後臺線程共享訪問我可能會建議斷言[NSThread isMainThread]

相關問題