Rob*_*ger 3 cocoa multithreading objective-c accessor thread-safety
我有一个应用程序(使用retain/release,而不是GC)来维护一个NSArray实例变量,它作为属性公开,如下所示:
@interface MyObject : NSObject
{
NSArray* myArray;
}
@property (copy) NSArray* myArray;
@end
Run Code Online (Sandbox Code Playgroud)
我想从辅助线程访问此数组的内容,该辅助线程使用分离-performSelectorInBackground:withObject:.在执行辅助线程期间,阵列可能并且实际上可能会发生变化.
在辅助线程中,我想做这样的事情:
if([self.myArray containsObject:foo])
{
//do stuff
}
Run Code Online (Sandbox Code Playgroud)
从阅读线程文档,似乎我应该能够@synchronized在访问器中使用该指令,如下所示:
@implementation MyObject
- (NSArray *)myArray
{
NSArray *result;
@synchronized(self)
{
result = [myArray retain];
}
return [result autorelease];
}
- (void)setMyArray:(NSArray *)aMyArray
{
@synchronized(self)
{
[myArray release];
myArray = [aMyArray copy];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
这是我需要做的就是确保线程安全,还是更复杂?
更新:我随后在Apple网站上发现了一篇很好的文章,深入解决了这个问题:http://developer.apple.com/mac/library/technotes/tn2002/tn2059.html
上面的代码可以保护您不会同时设置数组,或者在另一个设置数组时获取数组.由于它是一个非可变数组,因此可以很好地保护数组本身.
但是,如果"数组将改变"意味着你将编辑数组中的项目,你仍然可能会遇到一些问题.例如,如果数组中填充了NSMutableStrings,并且您有一个运行的线程:
NSMutableString *foo = [myObject.myArray objectAtIndex:0];
[foo appendString:@"foo"];
Run Code Online (Sandbox Code Playgroud)
和另一个跑了
NSMutableString *bar = [myObject.myArray objectAtIndex:0];
[bar appendString:@"bar"];
Run Code Online (Sandbox Code Playgroud)
对数组的访问是安全的(一个线程必须等待另一个线程才能访问它),但是,访问foo/bar指针(它是相同的)不会,因为对'appendString'的两次调用都是在@synchronized块之外.
如果这是您的阵列将如何更改,您还需要同步这些访问点.有更多@synchronized块或其他类型的锁.请参阅使用锁
| 归档时间: |
|
| 查看次数: |
3777 次 |
| 最近记录: |