Obj-c: возвращение NSArray из метода - объекты вне области видимости - PullRequest
0 голосов
/ 29 января 2011

Мой вопрос очень похож на этот вопрос , но с некоторыми отличиями.

У меня есть класс, который принимает в XML int форму NSString, анализирует некоторые объекты и возвращает их в NSArray примерно так:

//Parser.m
+(NSArray *)parseMessagesFromXml:(NSString *)xml
{
   NSMutableArray *messages = [[NSMutableArray alloc] init];

   //do some work parsing the xml
   //for each <row>
   //   Message *m = makeMessageFromRow(row);

   return [messages autorelease];
}

Затем вМой класс контроллера представления Я объявляю NSArray:

//MyViewController.h
NSArray *messages;
@property (nonatomic, retain) NSArray *messages;

и назначаю его, используя метод выше:

//MyViewController.m
messages = [Parser parseMessageFromXml:xml];
[[self tableView] reloadData];

Итак, возникает проблема: когда я присваиваю массив messagesв нем есть элементы, но все они находятся вне области видимости.Я отладил проблему и знаю, что метод синтаксического анализа правильно создает объекты и добавляет их в NSMutableArray перед его возвратом.Когда я пытаюсь получить доступ к объектам в messages, мое приложение вылетает, и отладчик говорит EXC_BAD_ACCESS.Что более странно, так это то, что: если я сохраняю массив в локальной переменной, он работает просто отлично:

NSArray *temp = [Parser parseMessageFromXml:xml]; 
//temp has all the right objects and they are in scope

messages = temp;
//messages has the objects, but cannot access them (they are out of scope).

Как будто я могу легально просматривать их в локальной области, но я не могу назначить ихпеременная-член.Я даже пробовал перебирать возвращаемый массив, добавляя каждый из них к messages по отдельности, но результат тот же: они выходят за рамки.Я совершенно не в курсе этого.

Что это за messages как переменная-член, которая не позволяет ему содержать эти объекты?

1 Ответ

2 голосов
/ 29 января 2011

Проблема в том, что массив освобождается. Когда вы вызываете autorelease в parseMessagesFromXml:, вы указываете массиву, что он должен быть освобожден когда-нибудь в будущем. Это происходит до того, как таблица перезагрузит свои данные. Вам нужно снова сохранить массив, чтобы предотвратить его освобождение. В этом случае это так же просто, как использование методов доступа для установки вашего свойства вместо прямой установки переменной экземпляра.

//MyViewController.m
self.messages = [Parser parseMessageFromXml:xml];
[[self tableView] reloadData];
...