2010-12-08 21 views
1

Eine iPad-App, die unter IOS3 einwandfrei funktioniert, schlägt unter IOS4.2 fehl. Sie verfügt über eine Klasse, die eine HTTP-Sitzung aus einer Operationswarteschlange ausführt und der Fehler mit dieser Aktivität verknüpft ist. Hier ist die Ausgabe der Konsole:IOS4.2-Anwendung wird mit EXC_BAD_ACCESS beendet

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

Lauf NSZombies aktiviert nichts ergeben hat, so habe ich NSLog Anweisungen im Code setzen und festgestellt, dass der Absturz tritt auf, wenn eine lokale Variable geändert wird. Hier ist der Code-Abschnitt:

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"); 

Und hier wird die Konsolenprotokollausgabe:

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] 

Es ist wie Status hat sich zu schreibgeschützt (Es ist Eigenschaft wird als atomare und Lese-Schreib erklärt).

Die andere relevante Information ist, dass eine Unteransicht gerade geändert wurde und es den Aufruf auf der obigen Routine auslöst. Es ist Code ist:

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

Hat jemand so etwas gesehen?

Hat jemand Ideen, wo als nächstes zu suchen?

Grüße Robin

Hier ist der 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:] 
+0

In Zukunft ** bitte ** überprüfen Sie Ihre Frage, um sicherzustellen, dass die Codeformatierung korrekt ist. – JeremyP

+0

Führen Sie dies auch im Debugger aus, rufen Sie den Stack-Trace ab und veröffentlichen Sie ihn hier. – JeremyP

+0

keine Chance, dass Sie einen benutzerdefinierten Setter für den Status haben, der den Absturz verursacht? Was passiert, wenn Sie in dieser Zeile einen Haltepunkt setzen und in die Datei self.status = IEnablerServiceUpdating wechseln? – Rog

Antwort

0

NSOperationQueue in iOS 4.2 jetzt Grand Central Dispatch verwendet, wenn NSOperations starten. There's a Technical Q&A here

So ziemlich die Warteschlange ruft nun die start Methode der NSOperation Unterklasse in einem neuen Thread unabhängig von der isConcurrent Eigenschaft. Meiner Erfahrung nach bedeutet das, dass wenn Sie NSURLConnection innerhalb einer start Methode verwenden, Ihr Code nicht mehr laufen wird, weil der Thread start läuft, hat keine NSRunLoop.

Apple sagt, dass diese Änderung nicht die Kompatibilität bricht, weil Sie sowieso einen neuen Thread in der start Methode spawnen sollten.

Aus Gründen der Abwärtskompatibilität sollten Sie Ihre Unterklasse von der Verwendung von start in die Verwendung von run ändern.

+0

Meine Nachforschungen zu GCD legen nahe, dass es für Dispatch-Warteschlangen (Concurrency Guide p13), nicht für Operationswarteschlangen, geeignet ist. Aber NSURLConnections sollte aus Operationswarteschlangen ausgeführt werden. Aber seit iOS3 ist der bessere Weg für diese aufgerufen werden, durch die asynchronen API-Aufrufe. Aber ich bin nicht willens/nicht in der Lage, den Code zu überarbeiten, da ich keinen Zugriff auf die Umgebung habe, um ihn vollständig zu testen. Arrgghhhh! –

Verwandte Themen