我想要一个方法来创建一个新对象或返回一个基于标识符字符串的现有对象。
这是我的:
@implementation MyObject {
}
@synthesize data = _data;
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
// these methods are the only ones to be used for managing the MyObject life cycle
+ (NSMutableDictionary *)objectsDict
{
static NSMutableDictionary *map = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
map = [NSMutableDictionary new];
});
return map;
}
+ (MyObject *)getRefrenceForId:(NSString *)identifier
{
return [[MyObject objectsDict] objectForKey:identifier];
}
+ (MyObject *)newRefrenceWithId:(NSString *)identifier
{
MyObject *obj;
@synchronized (self) {
obj = [[MyObject objectsDict] objectForKey:identifier];
if (obj == nil) {
obj = [[MyObject alloc] init];
obj.identifier = identifier;
[[MyObject objectsDict] setObject:obj forKey:identifier];
NSLog(@"new instance of MyObject created with id:%@",identifier);
}
}
return obj;
}
+ (MyObject *)newRefrenceWithId:(NSString *)identifier andClassType:(Class)classType
{
MyObject *obj;
@synchronized (self) {
obj = [[MyObject objectsDict] objectForKey:identifier];
if (obj == nil) {
obj = [[MyObject alloc] initWithClassType:classType andId:identifier];
[[MyObject objectsDict] setObject:obj forKey:identifier];
NSLog(@"new instance of MyObject created with id:%@ of ClassType :%@",identifier,NSStringFromClass(classType));
}
}
return obj;
}
+ (void)deleteInstance:(NSString *)identifier
{
@synchronized (self) {
[[MyObject objectsDict] removeObjectForKey:identifier];
}
}
+ (void)clearAllMyObjectsFromMap
{
@synchronized (self) {
[[MyObject objectsDict] removeAllObjects];
}
}
有更好的方法吗?我听说 @synchronized 的 CPU 开销很大,但是 GCD 并发队列不能用在类方法中...
更新:全局同步队列应该在哪里……在初始化中?那是一个实例方法,所以我不在那里工作......
最佳答案
您可以使用 GCD:
在模块范围内定义的自由函数中使用
dispatch_once
创建全局“同步队列”:static dispatch_queue_t get_sync_queue() { static dispatch_once_t onceToken; static dispatch_queue_t sync_queue; dispatch_once(&onceToken, ^{ sync_queue = dispatch_queue_create("my.sync_queue", DISPATCH_QUEUE_CONCURRENT); }); return sync_queue; }
将此队列与
dispatch_sync
和修改对象的 block 一起使用:+ (MyObject *)newRefrenceWithId:(NSString *)identifier { __block MyObject *obj; dispatch_barrier_sync(get_sync_queue(), { obj = [[MyObject objectsDict] objectForKey:identifier]; if (obj == nil) { obj = [[MyObject alloc] init]; obj.identifier = identifier; [[MyObject objectsDict] setObject:obj forKey:identifier]; NSLog(@"new instance of MyObject created with id:%@",identifier); } }); return obj; }
方法 newRefrenceWithId:
现在是完全线程安全的。
编辑:
或者,您也可以使用并发 sync_queue 并在 block 中读取和写入时使用dispatch_barrier_sync
(如您的情况)
写入对象时使用dispatch_barrier_async
。
如果您只需要读取 并返回共享对象的状态,您应该使用dispatch_sync
- 它允许并发读取。
关于ios - @sychronized 替代类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25021512/