我有一些代码:
//in the interface file
//...
NSMutableSet * someSet;
//...
//
//in the implementation file
//-(id)init {
if(self = [super self])
{
someSet = [[NSMutableSet alloc] init];
}
return self;
}
-(void)someFunc
{
NSLog(@"someSet count: %lu", [someSet count]); //always shows some number
array = ... //getting array from another function
for(SomeObject * obj in array)
{
NSSomeOperation * op = [[NSSomeOperation alloc] initWithValue:[obj someValue]];
//start operation
[someSet addObject:[obj someValue]];
}
}
//this function is called from another thread (from operation) through notification
//
-(void)someAnotherFunc
{
@synchronized(self)
{
int size = [someSet count]; //HERE size = 0, but it must be some count
NSLog(@"someSet: %@", someSet); // it outputs: "someSet: {()}"
NSLog(@"someSet count: %lu", [someSet count]); // it outputs: "someSet count: (null)"
}
}
问题是,someAnotherFunc中的size = 0,但它必须是一些计数。我知道,这是因为someAnotherFunc是从另一个线程调用的,在那个线程中someSet = nil。
我已经尝试过performSelectorOnMainThread但它没有帮助。
更新
我调试了这个,我调用了两次someFunc,someSet在这些调用期间是有效的对象,并且有一些对象的数量。我在someFunc中记录了count - 并输出了有效的对象数。
只有在启用ARC时才会启用,在启用ARC之前 - 一切都很好。
似乎是线程或ARC的一些安全性,以防止使用来自不同线程的数据。也许我不对,但我不明白为什么会这样。
在执行这段代码期间,someSet不会直接分配给nil。它没有被解除分配。
有谁知道如何从另一个线程访问someSet对象?如何在someSet中获取有效的对象数?
答案 0 :(得分:2)
该代码没有任何与线程相关的错误(除此之外,您将通过尝试以这种方式进行线程来遇到一系列无关的问题。)
某处,someSet
在运行其他线程代码之前被设置为nil。你说这只会在启用ARC的情况下发生吗?那么这很可能是因为你没有对封装该代码的任何对象的强引用;即对象正在被释放,因为编译器已确定它已不再被使用。
这很可能是因为处理通知的代码未设置为保留观察者 - 以保持对观察者的引用。直接或间接地在全局变量中粘贴对观察者的引用。
请注意,该代码中的@synchronize()
可能是无意义的,或者,如果您确实有多个可能触发通知的线程,则表明存在体系结构问题。
另请注意,如果NSLog(@"someSet count: %@", [someSet count]); // it outputs: "someSet count: (null)"
设置正确,someSet
将会崩溃。