如何在Objective-C中使用本地靜態對象?如何在Objective-C中使用本地靜態對象?
- (void)foo {
static NSMutableArray *mutableArr = nil;
// initialize mutableArr somehow somewhere
// using mutableArr several times
}
如何在Objective-C中使用本地靜態對象?如何在Objective-C中使用本地靜態對象?
- (void)foo {
static NSMutableArray *mutableArr = nil;
// initialize mutableArr somehow somewhere
// using mutableArr several times
}
我希望我沒有錯過什麼,但這是我如何使用它:
- (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...
}
FWIW,這對於來自多個線程的併發訪問而言不是線程安全的。也就是說,如果您要將共享引用出售給單個可變數據結構,那麼您已經使該方法的所有不同調用者的作業都成爲線程安全的。 – ipmcc
if use static var。在初始化var之前檢查它是否被初始化是一種好方法。
如果你的目標很簡單,就是有一個單身,似乎對於這些共同的,公認的模式天如下:
#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]
。
@KevinBallard是的,我覺得Objective-C的也許支持。 – Nickolas
@KevinBallard在C中,你不需要關心引用計數。在這裏,我必須保持計數並在某個時候釋放它。我想知道是否有一個簡單的方法來做到這一點。 – Nickolas
@Nickolas:靜態變量存在於程序的整個生命週期中。如果你希望對象具有普通對象的使用壽命,爲什麼使用靜態?我想我錯過了你所設想的用法。 – Chuck