0

I have an application in Xcode 4.6 that connects with Facebook. I have noticed that every so often when the application goes into the background and returns to the foreground, there are occasional crashes at varying points in the application. Being inconsistent, the crashes were difficult to analyze, so I tried using instruments to identify memory leaks. I am quite new to iOS, and although I was able to successfully determine that I do have memory leaks, and I can even see which methods are triggering them, I find myself thinking, "well what now?" In other words, I see where the problem is, but yet I can't identify it. I am hoping if I highlight an example, someone can shed some light.

**Here is what I am looking at in instruments:

instruments screen shot

Just looking at the first leaked object in the list:

Leaked Object = "FB Session"

Responsible Frame =

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

I interpret this to mean that there is some leaked object existing inside of this method. Is that correct? The implemented method exists in my App Delegate and looks like:

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

At this point, I am not sure what I need to do, or what about this method could even be causing a leak. I have looked though memory leak tutorials, but they only got me to the point of locating the problem, but stop short of helping me figure out how to solve it. Any help is appreciated.

Community
  • 1
  • 1
jac300
  • 5,182
  • 14
  • 54
  • 89

1 Answers1

1

Generally you shouldn't pass self to block as block retains it. It seems, that FBSession also retains completionHandler, so it becomes a retain cycle.

In order to break it, use one of the following constructions:

__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

and then

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

See this post for more complete explanation of what retain cycles are.

Community
  • 1
  • 1
kovpas
  • 9,553
  • 6
  • 40
  • 44