2014-02-28 2 views
6

Ich habe Google Analytics für mehrere iOS-Apps verwendet. Keine Probleme. Dieses Mal, Problem.iOS Google Analytics Speicher wächst außer Kontrolle FAST

Ich mache die grundlegende Einrichtung mit Version 3.0. Fügen Sie eine Bibliothek/Kopfzeile hinzu, fügen Sie die erforderlichen Frameworks hinzu und stopfen Sie den Code der Kesselbleche in die AppDelegate.m ein. So weit, so gut, alles funktioniert wie erwartet. Ich nehme meine erste UIViewController und ändere es um GAITrackedViewController zu erweitern und es trifft den Lüfter. Die App friert auf dem ersten Bildschirm ein und die Speicherauslastung steigt um 4 Megapixel pro Sekunde. Also wechsle ich die UIViewController zurück und alles ist gut. Ich versuche, den Bildschirmnamen manuell in viewDidLoad aufzurufen.

// Analytics 
id tracker = [[GAI sharedInstance] defaultTracker]; 
[tracker set:kGAIScreenName value:@"Initial"]; 
[tracker send:[[GAIDictionaryBuilder createAppView] build]]; 

Das Gleiche passiert. Mein View-Controller hat einige benutzerdefinierte Container-Ansichten und den Root-View-Controller auf einem generischen UINavigationViewController. Ich denke, es sind wahrscheinlich die benutzerdefinierten Container, die den aktiven View-Controller und den zu verwendenden Bildschirmnamen verwirren (aber ich sehe kein Anzeichen dafür in der Protokollierung).

Hat jemand auf dieses Problem gestoßen und konnte genau feststellen, was es verursacht und wie man es umgehen kann?

+0

Instrumente verwenden. Was wird zugeteilt? Woher? – Wain

+1

Slews von 'CFString' und' CFURL' von 'URIRepresentation'-Methode für die Klasse' NSManagedObjectID'. Viele kleine. Ich kann nicht (vielleicht weiß ich einfach nicht) viel darüber hinaus sagen, weil es aussieht, als käme es aus Googles Bibliothek. – DBD

Antwort

5

João Antwort ist richtig, aber ich mag es erklären.

Von Getting Started Dokuments Google

Wenn Ihre App verwendet die Coredata Rahmen: auf eine Meldung reagiert, z.B. NSManagedObjectContextDidSaveNotification aus dem Google Analytics-CoreData-Objekt Google kann zu einer Ausnahme führen. Stattdessen empfiehlt Apple , CoreData-Benachrichtigungen zu filtern, indem Sie den verwalteten -Objektkontext als Parameter für Ihren Listener angeben.

Was das bedeutet, ist ...

// This code will cause a problem because it gets triggered on ANY NSManagedObjectContextDidSaveNotification. 
// (both your managed object contact and the one used by Google Analytics) 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(managedObjectContextDidSave:) 
             name:NSManagedObjectContextDidSaveNotification 
             object:nil]; 

// This code is safe and will only be trigger from the notification generated by your Managed Object Context. 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(managedObjectContextDidSave:) 
             name:NSManagedObjectContextDidSaveNotification 
             object:myManagedObjectContext]; 

Nun lese ich die Dokumentation und ich hatte dies richtig gemacht, aber ich hatte immer noch das Problem. Es stellte sich heraus, dass ich meinen Code für das Entfernen der Benachrichtigung nicht aktualisiert habe.

// Not Safe 
[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:NSManagedObjectContextDidSaveNotification 
               object:nil]; 

// Safe 
[[NSNotificationCenter defaultCenter] removeObserver:self 
               name:NSManagedObjectContextDidSaveNotification 
               object:myManagedObjectContext]; 

Die Moral der Geschichte ist, achten Sie auf Ihre Benachrichtigung Listener. Es dauert ein paar Sekunden, um einen Listener für ein bestimmtes Objekt anzugeben, und es kann eine lange Zeit dauern, ein Problem zu beheben, weil Sie versehentlich Ereignisse abhören, die Sie nicht möchten, oder Ereignisse abhören.

3

Ich hatte genau das gleiche Problem. Ich habe es geschafft, die Lösung in meinem Fall zu finden: Ich war zu NSManagedObjectContextDidSaveNotification Registrierung ohne den Kontext zu spezifizieren:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(managedObjectContextDidSave:) 
             name:NSManagedObjectContextDidSaveNotification 
             object:nil]; 

diesen Listener entfernen gelöst meine aus Gedächtnisprobleme.

Prost

4

Lösung 1: eine spezifische moc auf object Parameter verwenden, wenn NSManagedObjectContextDidSaveNotification Beobachten, damit Sie sich nur auf der angegebenen moc spart beobachten.

[[NSNotificationCenter defaultCenter] addObserver:self 
            selector:@selector(managedObjectContextDidSave:) 
            name:NSManagedObjectContextDidSaveNotification 
            object:managedObjectContext]; 

Lösung 2: Wenn Sie die Core Data Technik der Verschmelzung mocs auf Hintergrund-Threads erstellt verwenden, können Sie in der vorgeschlagenen Weise nicht leicht lösen können, so dass die alternative Ihre Methode zu ändern, ist die Meldung, um Griffe um zu vermeiden, dass die persistentStoreCoordinator des gespeicherten Moc nicht mit der persistentStoreCoordinator Ihres Hauptmoc übereinstimmt.

- (void)managedObjectContextDidSave:(NSNotification *)notification { 
    if ([NSThread isMainThread]) { 
     NSManagedObjectContext *savedMoc = notification.object; 

     // Merge only saves of mocs that are not my managedObjectContext 
     if (savedMoc == self.managedObjectContext) { 
      return; 
     } 

     // Merge only saves of mocs that share the same persistentStoreCoordinator of my managedObjectContext (i.e.: ignore the save of Google Analytics moc) 
     if (savedMoc.persistentStoreCoordinator != self.managedObjectContext.persistentStoreCoordinator) { 
      return; 
     } 

     [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification]; 
    } 
    else { 
     [self performSelectorOnMainThread:@selector(handleBackgroundContextSaveNotification:) withObject:notification waitUntilDone:YES]; 
    } 
}