Как получить доступ к объекту основного потока из другого потока? - PullRequest
1 голос
/ 01 марта 2012

У меня есть кусок кода:

//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)"
    } 
}

Проблема в том, что size = 0 в someAnotherFunc, но это должно быть некоторое количество. И я знаю, это потому, что someAnotherFunc вызывается из другого потока, а в этом потоке someSet = nil.

Я пытался выполнить executeSelectorOnMainThread, но это не помогает.

UPDATE:

Я отлаживал это, дважды вызывал someFunc, и someSet является допустимым объектом во время этих вызовов и имеет некоторое количество объектов. Я записал количество в someFunc - и выводит правильное количество объектов.

Это происходит только при включенной ARC, до того, как ARC был включен - все было хорошо.

Кажется, это защита от потоков или ARC для предотвращения использования данных из разных потоков. Может быть, я не прав, но я не понимаю, почему это происходит.

Во время выполнения этого фрагмента кода someSet напрямую не назначается nil. И это не освобождается.

Кто-нибудь знает, как получить доступ к объекту someSet из другого потока? Как получить действительное количество объектов в someSet?

1 Ответ

2 голосов
/ 02 марта 2012

Нет ничего не связанного с потоком неправильно с этим кодом (кроме того, что вы будете сталкиваться с множеством не связанных проблем, пытаясь выполнить многопоточность таким образом).

Где-то someSet находится в процессеустановите значение nil до запуска кода другого потока.Вы говорите, что это происходит только при включенном ARC?Тогда это наиболее вероятно, потому что у вас нет строгой ссылки на какой-либо объект, инкапсулирующий этот код;т.е. объект освобождается, потому что компилятор определил, что он больше не используется.

Это наиболее вероятно, потому что ваш код, который обрабатывает уведомление, не настроен для сохранения наблюдателя - чтобы сохранить ссылку нанаблюдатель - вокруг.Вставьте ссылку на наблюдателя в глобальной переменной, прямо или косвенно.

Обратите внимание, что @synchronize() в этом коде, скорее всего, бессмысленно или, если у вас действительно есть несколько потоков, которые могут запускать уведомление, показательноархитектурной проблемы.

Обратите также внимание, что NSLog(@"someSet count: %@", [someSet count]); // it outputs: "someSet count: (null)" вылетит, если someSet когда-либо будет правильно установлен.

...