Как получить доступ к другим объектам из NSOperation? Проблемы с потоками приводят к сбою - PullRequest
0 голосов
/ 28 июня 2009

У меня есть приложение, которое выполняет вход в веб-сервис, а затем запрашивает список объектов, используя sessionid, полученный во время входа в систему.

Appdelegate.h

....
@property (nonatomic, retain) NSString *sessionId;

AppDelegate.m:

-(id)init{
        queue = [[NSOperationQueue alloc] init];
        [queue setMaxConcurrentOperationCount:1];
.....
}

- (void)applicationDidFinishLaunching:(UIApplication *)application {
        LoginOperation *loginOperation = [[LoginOperation alloc] init];
        [queue addOperation:loginOperation];
        [loginOperation release];
      ListOperation *listOperation = [[ListOperation alloc] init];
      [queue addOperation:listOperation];
      [listOperation release];

}

LoginOperation:

-(void) main {
...
[[UIApplication sharedApplication] delegate] setSessionId:sessionID];
...

}

ListOperation:

-(void)main{
//Crashes at next line:
NSString *sessionId = [[UIApplication sharedApplication] delegate] sessionId] ;
}

Вылетает, если я получаю доступ к любому объекту в любом одноэлементном объекте или AppDelegate. Отладчик показывает, что одноэлементный объект или Appdelegate действителен и инициализирован, но ЛЮБОЕ свойство этого объекта недопустимо, и доступ приводит к сбою.

Это странная ошибка, связанная с потоками. Единственное, о чем я могу думать, это то, что NSOperation имеет недопустимые копии всех других объектов в своем потоке или что-то в этом роде.

Не происходит сбой, если делать то же самое в порожденном вручную потоке, используя [NSThread detachNewThreadSelector: @selector (executeList) toTarget: self withObject: nil]; Я хочу использовать NSOperation вместо NSThread detach ... потому что NSOperation предоставляет очередь.

Каков оптимальный шаблон для такой ситуации? определить ListOperation как параллельную операцию? Я не хочу сложной путаницы с определением параллельной операции.

Я думаю, что мой случай довольно прост, и должно быть простое решение?

Ответы [ 3 ]

1 голос
/ 22 октября 2010

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

http://www.markj.net/iphone-memory-debug-nszombie/

0 голосов
/ 29 июня 2009

Включите зомби (переменная окружения NSZombieEnabled), чтобы увидеть, не превышаете ли вы.

Записать [[[UIApplication sharedApplication] делегат] sessionId], чтобы проверить, что это такое перед строкойWithString (если бы это было ноль, это вызвало бы исключение).

Кстати, [NSString stringWithString: xxx] не делает абсолютно ничего полезного. Что бы вы ни пытались выполнить, это не поможет - перечитайте правила управления памятью .

Добавьте NSLog в начале / конце каждой основной сети, чтобы убедиться, что они синхронны, как вы ожидаете.

И "это дает сбой" на самом деле слишком размыто для вопроса, пожалуйста, включите более подробную информацию о возврате аварии.

0 голосов
/ 28 июня 2009

Вы можете добавить одну операцию как зависимость для другой. Тогда гарантируется, что другой не будет выполнен до завершения зависимой операции. Кроме того, везде, где вы используете sessionID в своем коде, вы должны убедиться, что операция входа в систему уже завершена. Пример добавления зависимостей на основе вашего кода:

- (void)applicationDidFinishLaunching:(UIApplication *)application {
      LoginOperation *loginOperation = [[LoginOperation alloc] init];
      ListOperation *listOperation = [[ListOperation alloc] init];
      [listOperation addDependency:loginOperation];
      [queue addOperation:loginOperation];
      [queue addOperation:listOperation];
      [loginOperation release];
      [listOperation release];
}

Теперь listOperation определенно не будет выполняться, пока loginOperation не завершится.

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