0

我在 Xcode 4.6 中有一个与 Facebook 连接的应用程序。我注意到,当应用程序进入后台并返回前台时,应用程序的不同点偶尔会发生崩溃。由于不一致,崩溃很难分析,所以我尝试使用工具来识别内存泄漏。我对 iOS 很陌生,虽然我能够成功确定我确实存在内存泄漏,甚至可以看到哪些方法触发了它们,但我发现自己在想,“现在怎么办?” 换句话说,我知道问题出在哪里,但我无法确定它。我希望如果我强调一个例子,有人可以阐明一些观点。

**这是我在仪器中看到的:

仪器屏幕截图

只需查看列表中的第一个泄漏对象:

泄漏对象 =“FB 会话”

负责框架 =

+[FBSession openActiveSessionWithPermissions:allowLoginUI:allowSystemAccount:isRead:defaultAudience:completionHandler:]

我将此解释为意味着此方法内部存在一些泄漏的对象。那是对的吗?实现的方法存在于我的 App Delegate 中,如下所示:

- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
  NSArray *permissions = [[NSArray alloc] initWithObjects:
                        @"user_about_me",
                        @"read_friendlists",
                        nil];
  //IMPLEMENTED METHOD
  return [FBSession openActiveSessionWithReadPermissions:permissions
                                          allowLoginUI:allowLoginUI
                                     completionHandler:^(FBSession *session,
                                                         FBSessionState state,
                                                         NSError *error) {
                                         [self sessionStateChanged:session
                                                             state:state
                                                             error:error];
                                     }];
}

在这一点上,我不确定我需要做什么,或者这种方法甚至可能导致泄漏。我看过内存泄漏教程,但它们只是让我找到了问题所在,但没有帮助我弄清楚如何解决它。任何帮助表示赞赏。

4

1 回答 1

1

通常,您不应将其传递self给 block,因为 block 会保留它。似乎 FBSession 也保留了completionHandler,所以它变成了一个保留循环。

为了打破它,请使用以下结构之一:

__weak FBSession *zelf = self; // OK for iOS 5 only
__unsafe_unretained FBSession *zelf = self; // OK for iOS 4.x and up
__block FBSession *zelf = self; // OK if you aren't using ARC

进而

return [FBSession openActiveSessionWithReadPermissions:permissions
                                      allowLoginUI:allowLoginUI
                                 completionHandler:^(FBSession *session,
                                                     FBSessionState state,
                                                     NSError *error) {
                                     [**zelf** sessionStateChanged:session
                                                         state:state
                                                         error:error];
                                 }];

有关保留周期的更完整说明,请参阅这篇文章。

于 2013-02-26T18:04:46.137 回答