iOS谷歌分析内存快速失控

6

我在几个iOS应用程序中使用了Google Analytics,没有问题。这次出现了问题。

我使用版本3.0进行基本设置,添加库/头文件,包括所需的框架,并将样板代码放入AppDelegate.m中。到目前为止,一切都正常,一切如预期工作。我将我的第一个UIViewController更改为扩展GAITrackedViewController,然后问题出现了。应用程序在第一个屏幕上冻结,并且内存使用量每秒增加约4兆字节。因此,我将UIViewController改回来,一切正常。我尝试在viewDidLoad中手动调用屏幕名称。

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

同样的事情发生了。我的视图控制器有几个自定义容器视图,它是通用 UINavigationViewController 上的根视图控制器。我想这可能是自定义容器混淆了活动视图控制器和要使用的屏幕名称(但我在日志中没有看到任何迹象)。
有人遇到过这个问题并且能够确定是什么原因以及如何解决吗?

使用工具。正在分配什么?在哪里分配? - Wain
1
NSManagedObjectID类的URIRepresentation方法返回大量的CFStringCFURL。有很多小的,但我无法(也许只是我不知道如何)进一步解释,因为它似乎是来自Google的库。 - DBD
4个回答

5

João的回答是正确的,但我想更详细地解释一下。

根据谷歌的入门文档

如果您的应用程序使用CoreData框架: 从Google Analytics CoreData对象响应通知, 例如NSManagedObjectContextDidSaveNotification,可能会导致异常。相反,Apple建议通过将托管对象上下文指定为侦听器的参数来过滤CoreData通知。

这意味着...

// 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];

现在我已经阅读了文档并正确地操作了,但问题仍然存在。事实证明,当我移除通知时,我没有更新我的代码。
// Not Safe
[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:NSManagedObjectContextDidSaveNotification 
                                              object:nil];

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

故事的寓意是,注意你的通知监听器。为特定对象指定监听器只需要几秒钟,而由于意外监听到不需要的事件或移除监听器而导致的调试问题可能需要很长时间。

4
解决方案1:在观察NSManagedObjectContextDidSaveNotification时,在object参数上使用特定的moc,这将允许您仅观察给定moc上的保存。
[[NSNotificationCenter defaultCenter] addObserver:self 
                                  selector:@selector(managedObjectContextDidSave:) 
                                  name:NSManagedObjectContextDidSaveNotification 
                                  object:managedObjectContext];

解决方案2: 如果你正在使用Core Data技术在后台线程合并moc,那么你不能轻易地按照建议的方式解决问题。因此,替代方法是更改处理通知的方法,以避免在保存的moc的persistentStoreCoordinator与主moc的persistentStoreCoordinator不匹配时进行合并。

- (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];
    }
}

3

我曾经遇到过完全相同的问题。 在我的情况下,我找到了解决方案:我注册了NSManagedObjectContextDidSaveNotification,但没有指定上下文:

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

移除此监听器解决了我内存不足的问题。

谢谢!


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接