如何从另一个线程访问主线程的对象?

时间:2012-03-01 19:41:36

标签: objective-c multithreading automatic-ref-counting

我有一些代码:

//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中获取有效的对象数?

1 个答案:

答案 0 :(得分:2)

该代码没有任何与线程相关的错误(除此之外,您将通过尝试以这种方式进行线程来遇到一系列无关的问题。)

某处,someSet在运行其他线程代码之前被设置为nil。你说这只会在启用ARC的情况下发生吗?那么这很可能是因为你没有对封装该代码的任何对象的强引用;即对象正在被释放,因为编译器已确定它已不再被使用。

这很可能是因为处理通知的代码未设置为保留观察者 - 以保持对观察者的引用。直接或间接地在全局变量中粘贴对观察者的引用。

请注意,该代码中的@synchronize()可能是无意义的,或者,如果您确实有多个可能触发通知的线程,则表明存在体系结构问题。

另请注意,如果NSLog(@"someSet count: %@", [someSet count]); // it outputs: "someSet count: (null)"设置正确,someSet将会崩溃。