2009-06-28 3 views
0

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

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] ; 
} 

Это сбой, если я пользуюсь любым proeprty в любом объекте singleton или AppDelegate. Отладчик показывает, что объект singleton или Appdelegate действителен и инициализирован, но свойство ANY этого объекта недействительно, и доступ приводит к сбою.

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

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

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

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

+0

звучит как состояние гонки или более выпущенный объект. Что такое sessionID? Что такое авария? Backtrace? Здесь недостаточно информации, чтобы отлаживать его как есть. – bbum

+0

Отладчик показывает, что объект, к которому я обращаюсь, действителен, но все свойства объекта недействительны. Я попытался получить доступ к некоторому объекту singleton из NSOperation и создать те же условия сбоя. Поэтому BAD_ACCESS аварийно завершает работу. – Rod

+0

Я попытался сделать это одновременным NSOperation, с помощью метода start() и всего остального. В руководстве говорится, что одновременное выполнение выполняется в новом потоке. Поэтому я подумал, что это может решить проблему. Но это не так. Крушение точно такое же! – Rod

ответ

0

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

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

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

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

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

+0

Регистрация [[[UIApplication sharedApplication] delegate] sessionId] приводит к сбою BAD ACCESS. Но Appdelegate - действительный объект! Очень странная проблема. – Rod

+0

@Roman. Это означает, что свойство sessionID переопределяется. Как попросил bbum, напишите код, в котором вы создаете фактический идентификатор сессии. –

+0

Включите NSZombieEnabled (в ваших исполняемых настройках, панели «Аргументы», добавьте переменную среды NSZombieEnabled = YES. Также отредактируйте свой вопрос и покажите ВСЕ код, который ссылается на sessionID. Скорее всего, вы неправильно его понимаете. –

0

Вы можете добавить одну операцию в качестве зависимости для другого. Затем другое гарантируется, что оно не будет выполняться до завершения зависимой операции. Кроме того, где угодно вы используете 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 завершается.

+0

Спасибо за подсказку. Однако это не решает мою проблему с доступом к sessionID изнутри NSOperation. – Rod

1

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

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