我希望有一个方法可以创建一个新对象,也可以根据标识符字符串返回一个现有对象。
这就是我所拥有的:
@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非常昂贵,但GCD并发队列不能用于类方法......
更新:init中的全局同步队列应该在哪里?这是一种实例方法,所以我在那里工作......
答案 0 :(得分:1)
您可以使用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
一起使用以及修改对象的块:
+ (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并在块中读取和写入时使用dispatch_barrier_sync
写对象时使用dispatch_barrier_async
。
如果您只需读取并返回共享对象的状态,则应使用dispatch_sync
- 这允许并发读取。