2012-06-06 3 views
6

Ich habe vor 2 Jahren eine riesige iPad App geschrieben und jetzt komme ich zurück und aktualisiere sie auf iOS5. Es ist ein bisschen unordentlich, da es meine erste große iPad App war.Tipps zum zeitweiligen Einfrieren der iOS UI

Es hat einen "Sync" -Schritt, der für einige Minuten dauern kann und das sind eine Reihe von asynchronen Methodenaufrufen, die JSON von einer URL holen und sie in Kerndaten ablegen. Ziemlich oft wird die App einfrieren (UI reagiert nicht mehr).

Was sind einige gute Techniken, um diesen Einfrieren aufzuspüren? Der Debugger ist nicht so hilfreich, es sei denn, der Code läuft im Hauptthread, Sie haben keinen verwendbaren Stack-Trace. Die App wird oft auch nicht wiederhergestellt, was auf eine Art Deadlock-Situation hindeutet.

Hier ist ein besonderes Beispiel, die helfen könnten:

enter image description here

Ich hielt inne, die Ausführung, sobald ich, dass es überprüft wurde eingefroren. Es scheint jedes Mal in der gleichen Zeile einzufrieren - eine einfache Aufgabe. Was geht hier vor sich? Es ist so frustrierend.

Ist dieser Kern Datenzugriff, der dies verursacht? Alle Hinweise würden sehr geschätzt werden.

EDIT 29-Juni-2012

Click here die Quelle der Klasse zu sehen, die alle FÜHRT/Update/Löschen von Objekten Kerndaten. Ich muss nur das Einfrieren/Absturz in dieser App stoppen. Ich weiß, es ist ein Durcheinander, es bringt mich auch zusammen. Ich schrieb dies vor 2 Jahren mit kaum Wissen von Ziel-c. Ich sollte es neu schreiben, aber ich muss das in zwei Tagen funktionieren lassen. Könnte mir jemand Hinweise auf Ansätze geben, um diese Thread-safe schnell zu bekommen? Könnte ich jede Methode, die NSManagedObjectContext im zentralen Code des zentralen Dispatchblocks aktualisiert, umbrechen?

+1

Wenn die Benutzeroberfläche nicht mehr reagiert, geschieht dies, weil Sie Code im Hauptthread ausführen, der im Hintergrund ausgeführt werden soll. Sie können versuchen, die App während dieses Einfrierens anzuhalten und hoffentlich einen nützlichen Stack-Trace auf dem Hauptthread zu erhalten ... aber Sie werden es wahrscheinlich nicht tun. Der einzige Weg, den ich in diesem Szenario als sehr hilfreich empfunden habe, ist, den Code, den du ausführst, und wo genau zu kritisieren. Überprüfen Sie alle Ihre Webanfragen und den zugehörigen Code sowie andere Bereiche, die Ihrer Meinung nach prozessintensiv sind. – Matt

+2

Eine andere Idee (anstatt im Debugger zu pausieren und auf das Beste zu hoffen) könnte sein, die App unter Instrumente laufen zu lassen, die Ihnen sagen wird, welche Methoden am meisten Zeit verbrauchen. Ich habe es sehr hilfreich gefunden, genau diese Probleme zu beheben. –

+0

Ich aktualisierte Frage mit Link zur Quelle - wenn das hilft. –

Antwort

2

Es ist in der Tat möglich, dass Core Data (in Kombination mit Multithreading) die Ursache Ihrer Probleme ist - ich hatte ähnliche Probleme.

Hier ist ein ausgezeichneter Artikel zu diesem Thema: Core Data and threads, without the headache

ich auch einen Anruf zu performSelector: in Ihrer Stack-Trace sehen. Sie sollten vielleicht überlegen, Grand Central Dispatch zu verwenden, obwohl das in Ihrem Fall eine Menge zu schreiben wäre.

Wie für Ihre eigentliche Frage (Deadlocks aufspüren), würde ich vorschlagen, Instrumente auch zu verwenden. Sehen Sie sich auch den Status der anderen Threads an.

+0

Also hatten Sie auch Gefrierprobleme? –

+0

Ja, ich hatte Probleme mit dem Einfrieren sowie allgemein seltsames Verhalten (und ein paar Abstürze). All dies könnte gelöst werden, indem die Verwendung von Core Data auf den Hauptthread reduziert wird, aber ich habe den Ansatz in dem erwähnten Artikel in einem Testprojekt ausprobiert und es funktioniert (mit mehreren Threads). –

0

Sie sagte:

Der Debugger wie es sei denn, der Code auf dem Haupt-Thread läuft nicht so hilfreich ist, haben Sie keine brauchbaren Stack-Trace haben.

Dies ist nicht wahr. Sie erhalten Stack-Traces für alle Threads.

Die Tatsache, dass es jedes Mal auf der gleichen Linie einfriert, legt sehr nahe, dass mit dieser Linie etwas nicht stimmt.Dies ist, was Sie tun:

self.friendObj.affiliations = friendObject1.affiliations; 

Also, ich würde auf dieser Linie einen Haltepunkt setzen und wenn Xcode auf der Breakpoint stoppt, analysieren die Erinnerung an friendObj1. Vielleicht ist etwas Unkonventionelles im Gange.

Gibt es eine benutzerdefinierte Methode "setAffiliations:" in der Klasse von friendObj? Vielleicht kommt irgendwie eine Endlosschleife auf dieser Linie vor.

Ich würde alle Anrufe rund um die Einstellung "Affiliations" -Eigenschaft von Ihrem FriendObj analysieren und versuchen, festzustellen, wo Ihr Fehler ist.

Ein anderer Gedanke: ist FriendObj ein Core Data Objekt? Wenn dies der Fall ist, sollte es in einem ManagedObjectContext initialisiert werden.

+0

Nein, es gibt keine benutzerdefinierte setAffiliations-Methode. Es ist nur eine Zeichenfolge @ Eigenschaft. friendObject1 ist ein Coredata-Objekt, das beim Debuggen fehlerhaft ist. Ich war jedoch nicht alarmiert, weil ich gehört habe, dass Kerndatenobjekte in einem Fehlerzustand sein können, wenn sie noch nicht vollständig gelöst sind. –

+0

Wenn friendObj ein NSManagedObject (Kerndatenobjekt) ist, sollte es mit [NSEntityDescription insertNewObjectForEntityForName: @ "ClassName" inManagedObjectContext: myManagedObjectContext] initialisiert werden. –

+0

friendObj ist KEIN NSManagedObject - friendObj1 IS obwohl. –