【问题标题】:iOS Google Analytics memory growing out of control FASTiOS Google Analytics 内存增长失控 FAST
【发布时间】:2014-02-28 17:42:30
【问题描述】:

我在多个 iOS 应用中使用过 Google Analytics。没问题。这一次,问题。

我使用 3.0 版进行基本设置。添加库/头文件,包括所需的框架,并将样板代码填充到AppDelegate.m。到目前为止一切顺利,一切都按预期工作。我拿了我的第一个 UIViewController 并将其更改为扩展 GAITrackedViewController 并且它击中了粉丝。该应用程序在第一个屏幕上冻结,内存使用量开始上升约 4Meg/秒。所以我把UIViewController改回来,一切都很好。我尝试在viewDidLoad 中手动调用屏幕名称。

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

同样的事情也会发生。我的视图控制器有几个自定义容器视图,它是通用UINavigationViewController 上的根视图控制器。我认为这可能是自定义容器混淆了哪个是活动视图控制器以及要使用的屏幕名称(但我在日志中没有看到任何迹象)。

有没有人遇到过这个问题并且能够准确地确定是什么导致了它以及如何解决它?

【问题讨论】:

  • 使用仪器。分配了什么?在哪里?
  • CFStringCFURL 来自 URIRepresentation 类的 URIRepresentation 方法。很多小的。我不能(也许我只是不知道如何)说更多,因为它看起来像是从谷歌的图书馆里出来的。

标签: ios memory google-analytics containers


【解决方案1】:

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

来自 Google 的 Getting Started 文档

如果您的应用使用 CoreData 框架:响应通知, 例如NSManagedObjectContextDidSaveNotification,来自 Google Analytics CoreData 对象可能会导致异常。相反,苹果 建议通过指定托管过滤 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];

这个故事的寓意是,注意你的通知听众。为特定对象指定侦听器需要几秒钟的时间,调试问题可能需要很长时间,因为您不小心侦听了您不想侦听的事件或删除侦听事件。

【讨论】:

    【解决方案2】:

    解决方案 1:在观察 NSManagedObjectContextDidSaveNotification 时在 object 参数上使用特定的 moc,这将允许您仅观察给定 moc 上的保存。

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

    解决方案 2:如果您正在使用合并在后台线程上创建的 moc 的 Core Data 技术,则无法以建议的方式轻松解决,因此替代方法是更改​​处理通知的方法为了避免在保存的 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];
      

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

      干杯

      【讨论】:

        【解决方案4】:

        我正在研究 XMPP 框架,并尽快修复了 GA 崩溃。这个失败了https://github.com/robbiehanson/XMPPFramework/blob/master/Extensions/CoreDataStorage/XMPPCoreDataStorage.m

        任何解决此问题的简单方法。

        https://github.com/robbiehanson/XMPPFramework/issues/577

        【讨论】:

          猜你喜欢
          • 2013-10-20
          • 2013-06-10
          • 2016-02-24
          • 2014-05-03
          • 1970-01-01
          • 2013-10-08
          • 1970-01-01
          • 2018-07-22
          • 1970-01-01
          相关资源
          最近更新 更多