问题描述
我在我的对象上创建一个KVC / KVO兼容的可变数组,推荐的方式:
@interface工厂{
NSMutableArray * widgets;
}
- (NSArray *)widgets;
- (void)insertObject:(id)obj inWidgetsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromWidgetsAtIndex:(NSUInteger)idx;
@end
显然这是一个棘手的线程安全问题。在 insert
和 remove
方法中我锁定数组访问以防止并发修改,因为。 / p>
我的问题是,实现 widgets
存取器的正确方法是什么?这是我的实现:
- (NSArray *)widgets {
[widgetLock lock];
NSArray * a = [[widgets copy] autorelease];
[widgetLock unlock];
return a;
}
是线程安全吗?
widgets
访问器应该没问题,虽然你应该注意,没有一个数组中的对象被锁定。所以,你可能遇到问题尝试并发运行代码 [[[myFactory widgets] objectAtIndex:7] setName:@ mildred];
和
[myTextField setStringValue:[[[myFactory widgets] objectAtIndex:7] name]]; // mildred?或者是其他东西?
由于数组中的对象未锁定,因此可能会遇到竞态条件或读写器/类型问题。是不是多线程是一种快乐?
另一方面,对于KVC合规,我建议实现 objectInWidgetsAtIndex:
和 countOfWidgets
而不是 widgets
存取器。记住,KVC模型关系,而不是数组属性。因此,你可以调用 [myFactory mutableArrayValueForKey:@widgets]
来获取表示 widgets
属性的数组。
I'm creating a KVC/KVO-compliant mutable array on one of my objects the recommended way:
@interface Factory {
NSMutableArray *widgets;
}
- (NSArray *)widgets;
- (void)insertObject:(id)obj inWidgetsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromWidgetsAtIndex:(NSUInteger)idx;
@end
Clearly this is a tricky thread-safety issue. In the insert
and remove
methods I'm locking around array access to prevent concurrent modification, as recommended.
My question is, what is the proper way to implement the widgets
accessor? Here's my implementation:
- (NSArray *)widgets {
[widgetLock lock];
NSArray *a = [[widgets copy] autorelease];
[widgetLock unlock];
return a;
}
Is it threadsafe?
Your widgets
accessor should be fine, although you should be aware that none of the objects in that array are locked. So, you could run into problems trying to concurrently run code like
[[[myFactory widgets] objectAtIndex:7] setName:@"mildred"];
and
[myTextField setStringValue:[[[myFactory widgets] objectAtIndex:7] name]]; // mildred? or something else?
Since the objects in your array are not locked, you could run into race conditions or readers/writers-type problems. Isn't multithreading a joy?
On a different note, for KVC-compliance, I'd advise implementing objectInWidgetsAtIndex:
and countOfWidgets
instead of a widgets
accessor. Remember, KVC models relationships, not array properties. So you would call something like [myFactory mutableArrayValueForKey:@"widgets"]
to get an array representing the widgets
property.
这篇关于Cocoa Threadsafe Mutable集合访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!