An iPad app that runs fine under IOS3 fails under IOS4.2 It has a class that runs an http session from an operation queue and the failure is linked to this activity. Here is the console output:
Program received signal: “EXC_BAD_ACCESS”.
[Switching to thread 11523]
Running NSZombies enabled didn't reveal anything so I have been putting NSLog statements in the code and found that the crash occurs when a local variable is changed. Here is the code section:
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");
And here is the console log output:
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]
It is like status has become read-only (It's property is declared as atomic and readwrite).
The other relevant piece of information is that a sub-view has just been changed and it triggers开发者_StackOverflow the call on the above routine. It's code is:
//Start the update
UCiEnablerAppDelegate *controller = (UCiEnablerAppDelegate *)[[UIApplication sharedApplication] delegate];
[controller deduceIEnablerServiceAccess];
controller.serviceBusy = TRUE; //1.04
Has anyone seen anything like this?
Has anyone ideas where to look next?
Regards Robin
Here's the stack trace:
#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:]
NSOperationQueue
in iOS 4.2 now uses GrandCentralDispatch when starting NSOperations
. There's a Technical Q&A here
Pretty much the queue now calls the NSOperation
subclass's start
method in a new thread regardless of the isConcurrent
property. In my experience it means that if you are using NSURLConnection
inside a start
method your code will no longer run because the thread start
is running on doesn't have an NSRunLoop
.
Apple says that this change doesn't break compatibility because you were supposed to spawn a new thread in the start
method anyway.
For backwards compatibility you should change your subclass from using start
to using run
.
精彩评论