It's the first time I'm fiddling around with iOS5 and ARC. So far, so good, it works, but I've run into some kind of a problem.
I have a custom UIStoryboardSegue
in which I use Facebook Connect (or other services) to log the user into my app. Simply put, it should do the following :
What happens instead, is that the login starts, but the segue is immediately released by ARC before it has any chance to complete.
I thought of a quick'n'dirty hack to prevent this:
@interface BSLoginSegue() {
__strong BSLoginSegue *_retained_self;
}
@end
// Stuff...
// Other stuff...
- (void) perform {
login();
_retained_self = self;
}
- (void) loginServiceDidSucceed:(BSLoginService *)svc {
...
_retained_self = nil;
}
The thing is, it really is a hack, so I was wondering if there were any other, and more elegant way I could do the same?
The idea that a class should need to retain itself suggests that there might be a design problem. When an object retains itself, it becomes unclear who owns it or who might have a reference to it, and the risk of a leak is high.
What class is responsible for presenting the segue? Is it the same class the contains the button? This class should retain the segue, present the segue, and then release the segue when/if the segue completes.
Without further insight into the view controller hierarchy, it's hard to give specific advice. But my first reaction is to suggest that the view controller that is deciding to present the segue or not should have a strong property on the segue. The subclassed segue might define a protocol that the presenting class may conform to to be advised as to when the segue should be nilled/released.
If you use Grand Central Dispatch (GCD) for concurrency (which you should, it's awesome!) then by putting a reference to your object in an Objective-C block and passing it into GCD, it will be automatically retained by the block until after the block has executed and itself been released.
Without knowing exactly how you're doing your async operations it's hard to give a definitive answer, but by using blocks and GCD you won't have to worry about this at all. The block will take care of retaining objects it references and ARC will do the rest.
It looks like you must be storing a reference to your UIStoryboardSegue
subclass somewhere, in order to call loginServiceDidSucceed:
on it, so perhaps just making that a strong reference will work. Once again, referencing it from a block (such as a completion block when the login succeeds) is ideal. I would recommend adapting your login code to use blocks for the success/failure callbacks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With