Сохранение объекта, созданного в NSThread - PullRequest
1 голос
/ 04 августа 2009

У меня есть следующий метод, который вызывается вызовом для нового потока (используя NSThread):

- (void) updateFMLs {   
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];

    [self performSelectorOnMainThread:@selector(doneLoading:) withObject:temp waitUntilDone:NO];
    [pool release];
}

Мой doneLoading: метод выглядит следующим образом:

- (void) doneLoading:(NSArray *)obj {
    myArray = [[NSArray alloc] initWithArray:obj copyItems:NO];
}

Содержимое myArray становится недействительным. Как я могу сохранить содержимое myArray, чтобы потом использовать его в своем приложении?

P.S. myArray определен в заголовочном файле класса.

Ответы [ 3 ]

1 голос
/ 04 августа 2009

Если ваш фоновый поток выполняет некоторую работу и ему нужно «передать» NSArray в ваш основной поток, то все, что нужно сделать doneLoading:

-(void)doneLoading:(NSArray *)obj
{
    [myArray release]; // release the previous array and its objects
    myArray = [obj retain];
    // now use myArray, refresh tables, etc.
}

Нет необходимости создавать еще одну копию массива, и это может быть основной проблемой. Вы также должны позвонить [temp release] после вашего performSelector вызова, поскольку аргументы для этого уже сохранены.

Если содержимое myArray каким-то образом становится действительным, то его куда-то выпускают вдвойне. myArray сохранит любые объекты, добавленные к нему. Вы упомянули, что myArray сам становится недействительным, поэтому попробуйте переписать фоновый поток и метод doneLoading с помощью этого шаблона.

Наконец, вы должны использовать [pool drain] вместо [pool release].

0 голосов
/ 06 августа 2009

Альтернативой вышеупомянутым опциям было бы объявление myArray как атомарного свойства в заголовке

@property (atomic,retain) NSArray *myArray;

Тогда в updateFML вы сможете просто вызывать сеттер из вторичного потока. Очевидно, это работает только в том случае, если вы готовы заплатить штраф за производительность для атомарного свойства.

- (void) updateFMLs {
    NSAutoreleasePool *pool - [[NSAutoreleasePool alloc] init];
    NSArray *temp = [[NSArray alloc] initWithArray:someArrayFromAnotherProcess];
    [self setMyArray:temp];
    [temp release];
    [pool drain];
}
0 голосов
/ 04 августа 2009

Код, который вы разместили, выглядит отлично, за исключением утечки памяти в updateFMLs. Вы, вероятно, переиздание объектов в другом месте. Я предполагаю, что это будет там, где someArrayFromAnotherProcess сделано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...