Приложение IOS4.2 закрывается с EXC_BAD_ACCESS

Приложение для iPad, которое нормально работает в IOS3, не работает в IOS4.2. У него есть класс, который запускает сеанс http из очереди операций, и сбой связан с этим действием. Вот вывод консоли:

Program received signal:  “EXC_BAD_ACCESS”.
[Switching to thread 11523]

Запуск NSZombies ничего не выявил, поэтому я поместил операторы NSLog в код и обнаружил, что сбой происходит при изменении локальной переменной. Вот раздел кода:

self.currentOperation = [[[DeduceAccessOperation alloc] init] autorelease];
[self.currentOperation addObserver:self forKeyPath:@"isFinished"
 options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
 context:NULL];
NSLog (@"Start observer added");    
[operationQueue addOperation:self.currentOperation];
NSLog (@"Start operation added");
NSLog(@"State is %d", self.status);
self.status = IEnablerServiceUpdating;
NSLog (@"State updated");

А вот вывод журнала консоли:

2010-12-08 21:26:44.548 UCiEnabler[5180:307] Start observer added
2010-12-08 21:26:44.550 UCiEnabler[5180:307] Start operation added
2010-12-08 21:26:44.552 UCiEnabler[5180:307] State is 1
Program received signal:  “EXC_BAD_ACCESS”.
[Switching to thread 11523]

Как будто статус стал доступен только для чтения (это свойство объявлено как атомарное и для чтения).

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

//Start the update      
UCiEnablerAppDelegate *controller = (UCiEnablerAppDelegate *)[[UIApplication sharedApplication] delegate];
[controller deduceIEnablerServiceAccess];
controller.serviceBusy = TRUE; //1.04

Кто-нибудь видел что-нибудь подобное?

У кого-нибудь есть идеи, куда смотреть дальше?

С уважением Робин

Вот трассировка стека:

#0  0x34a80464 in objc_msgSend
#1  0x3119543e in NSKVOPendingNotificationCreate
#2  0x3119535a in NSKeyValuePushPendingNotificationPerThread
#3  0x3117009a in NSKeyValueWillChange
#4  0x311682c6 in -[NSObject(NSKeyValueObserverNotification) willChangeValueForKey:]
#5  0x311cc718 in _NSSetIntValueAndNotify
#6  0x000097ce in -[IEnablerService startDeducingAccessState] at IEnablerService.m:55
#7  0x00002bc0 in -[UCiEnablerAppDelegate deduceIEnablerServiceAccess] at UCiEnablerAppDelegate.m:100
#8  0x0000a33e in -[RootViewControlleriPad animationDidStop:finished:context:] at RootViewController-iPad.m:43
#9  0x341bb336 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]

person Robin Harrington    schedule 08.12.2010    source источник
comment
В будущем пожалуйста просмотрите свой вопрос, чтобы убедиться в правильности форматирования кода.   -  person JeremyP    schedule 08.12.2010
comment
Кроме того, запустите это в отладчике, получите трассировку стека и опубликуйте ее здесь.   -  person JeremyP    schedule 08.12.2010
comment
нет шансов, что у вас есть настраиваемый сеттер для статуса, который вызывает сбой? Что произойдет, если вы установите точку останова в этой строке и войдете в self.status = IEnablerServiceUpdating?   -  person Rog    schedule 08.12.2010
comment
@Рог: может быть. Я думал, что какой-то KVO споткнулся, поэтому я хочу увидеть трассировку стека.   -  person JeremyP    schedule 08.12.2010


Ответы (1)


NSOperationQueue в iOS 4.2 теперь использует GrandCentralDispatch при запуске NSOperations. здесь технические вопросы и ответы

Практически очередь теперь вызывает метод start подкласса NSOperation в новом потоке независимо от свойства isConcurrent. По моему опыту, это означает, что если вы используете NSURLConnection внутри метода start, ваш код больше не будет выполняться, потому что поток, в котором выполняется start, не имеет NSRunLoop.

Apple говорит, что это изменение не нарушает совместимость, потому что вы все равно должны были создать новый поток в методе start.

Для обратной совместимости вы должны изменить свой подкласс с использования start на использование run.

person wm_eddie    schedule 08.12.2010
comment
Мое исследование GCD показывает, что оно подходит для очередей отправки (Руководство по параллелизму, стр. 13), а не для очередей операций. Но NSURLConnections должны запускаться из очередей операций. Но начиная с iOS3 лучший способ для их вызова — через асинхронные вызовы API. Но я не хочу/не могу пересматривать код, так как у меня нет доступа к среде, чтобы полностью его протестировать. Аааааа! - person Robin Harrington; 15.12.2010