Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development > iPhone SDK Development - Advanced Discussion

Reply
 
LinkBack Thread Tools Display Modes
Old 02-04-2011, 07:15 PM   #1 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default How do I get this code to be approved by the Analyzer?

I love the idea of using the Analyze function of XCode4 to catch potential memory leaks. But I can't get it to understand that allocating an object, and releasing it in a delegate method is not a memory leak. Here's the simplest example of code I could find that demonstrates this:
Code:
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    UIView *view = [self.view.window viewWithTag:kActivityTag];
    [view removeFromSuperview];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"CantConnectAppStoreTitle", @"")
                                                    message:NSLocalizedString(@"CantConnectAppStoreMessage", @"")
                                                   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [alertView release];
    UIView *view = [self.view.window viewWithTag:kActivityTag];
    [view removeFromSuperview];
    if (productArray == nil) [self dismissModalViewControllerAnimated:YES];
}
Here, the alertView is alloc'ed in the first function, and released when the delegate method is called. Since I know the delegate method has to be called, there's no chance of a memory leak. How do I get Analyze, or "Build and Analyze" on XCode3, to stop reporting this as a leak?
JasonR is offline   Reply With Quote
Old 02-04-2011, 07:38 PM   #2 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Release it after you show it. Why are you splitting it up, especially since it is the first thing you do in the delegate method?
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 02-04-2011, 11:29 PM   #3 (permalink)
Registered Member
 
Join Date: Apr 2010
Posts: 78
bigdiggyiPhone is on a distinguished road
Default

Code:
[[alert show] autorelease];
Quote:
Originally Posted by JasonR View Post
I love the idea of using the Analyze function of XCode4 to catch potential memory leaks. But I can't get it to understand that allocating an object, and releasing it in a delegate method is not a memory leak. Here's the simplest example of code I could find that demonstrates this:
Code:
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
    UIView *view = [self.view.window viewWithTag:kActivityTag];
    [view removeFromSuperview];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"CantConnectAppStoreTitle", @"")
                                                    message:NSLocalizedString(@"CantConnectAppStoreMessage", @"")
                                                   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    [alertView release];
    UIView *view = [self.view.window viewWithTag:kActivityTag];
    [view removeFromSuperview];
    if (productArray == nil) [self dismissModalViewControllerAnimated:YES];
}
Here, the alertView is alloc'ed in the first function, and released when the delegate method is called. Since I know the delegate method has to be called, there's no chance of a memory leak. How do I get Analyze, or "Build and Analyze" on XCode3, to stop reporting this as a leak?
__________________
Check out my apps:
  • Friis-It NF. Easily calculate the Noise Figure, Sensitivity, and gain of an RF receiver design.
  • RetireMax. Get a dose of reality about that next purchase!
bigdiggyiPhone is offline   Reply With Quote
Old 02-05-2011, 01:29 AM   #4 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Well, I'm splitting it up because I don't see anyone with a reference to it after I show it. I guess there's a secret retain in effect when I show? I can't find anything in the documentation about it.
JasonR is offline   Reply With Quote
Old 02-05-2011, 02:10 AM   #5 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

OK, I think I was able to get rid of all those warnings. Apparently show must retain the UIAlertView. But now I have code in my In App Purchase code that has the same problem. Here's the sample code from Apple, and it causes the same warning from the Analyzer:
Code:
- (void) requestProductData
{
   SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers: [NSSet setWithObject: kMyFeatureIdentifier]];
   request.delegate = self;
   [request start];
}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *myProduct = response.products;
    // populate UI
    [request autorelease];
}
Any idea how to get this code to pass the Analyzer? It doesn't look like I can safely autorelease the request immediately after the start call.
JasonR is offline   Reply With Quote
Old 02-05-2011, 11:44 AM   #6 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

If autorelease doesn't work, then just make a property for it.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 02-09-2011, 01:18 AM   #7 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Thanks for the first answer, it worked great. For the second one, is there an easy way to autorelease a value stored in a property? The only way I can see is to store it in a local variable and retain and autorelease it.

Or does anyone know for sure if an SKProductRequest has to be autoreleased after the delegate method is called?
JasonR is offline   Reply With Quote
Old 02-09-2011, 06:47 AM   #8 (permalink)
Registered Member
 
Chobie's Avatar
 
Join Date: Feb 2011
Location: UK
Posts: 115
Chobie is on a distinguished road
Default

Quote:
Originally Posted by JasonR View Post
Thanks for the first answer, it worked great. For the second one, is there an easy way to autorelease a value stored in a property? The only way I can see is to store it in a local variable and retain and autorelease it.

Or does anyone know for sure if an SKProductRequest has to be autoreleased after the delegate method is called?
The last time I had a similiar problem was with MKReverseGeocode. In the end I made a property for it which retained it and released it in dealloc. Checking if the object is null before releasing to prevent bad access errors.

Is there a reason why you are using autorelease instead of release? It appears to me it is at the end of its use in the code samples provided above.
__________________
Chobie is offline   Reply With Quote
Old 02-09-2011, 09:30 AM   #9 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

The reason I'm using autorelease is because all the Apple sample code does. I'm chicken to do a regular release because the documentation is so slim that I don't know how long the request needs to stay around after the callback.

Sounds like a property to keep it around until dealloc of the view controller is the safest option. Thanks everyone.
JasonR is offline   Reply With Quote
Old 02-09-2011, 10:09 AM   #10 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Well, you should release all retain and copy properties in dealloc, but that doesn't mean you need to keep the object alive until the view controller dies.

The first thing to do is be cognizant of your memory management responsibilities. So you could alloc it in the first method, and since you are given a reference to the same object you can release it in the second method. Even if Xcode doesn't recognize this as correct, you know it is correct.

If you want to clear up the warning, the next thing you should try is autoreleasing the object, either when you create it, or at minimum within the same method. I can't say for certain if this will work (meaning the object will live long enough) since it is different for different classes in different situations. So, try it in a few different scenarios (devices) and see if it works. If it does, you're good.

If that doesn't work, then use a property.

Code:
SKProductsRequest *request = ...
[self setTheRequestProperty:request];
[request release], request = nil;
Your obligations have been met, and the object will still be alive in the delegate method. But if you don't have a reason to keep it alive beyond that, then clear out the property in the delegate method:

Code:
[self setTheRequestProperty:nil];
Quote:
Originally Posted by Chobie View Post
Checking if the object is null before releasing to prevent bad access errors.
An unnecessary step. If it is nil, the release doesn't do anything.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 02-09-2011, 05:28 PM   #11 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

Brian, the main problem is that I know the existing code works fine, but I hate having warnings from the analyzer. The other problem is that since the official Apple sample code autorelease's the variable at the end of the delegate method, it makes me think maybe there's some hidden reason the variable has to be alive when the delegate method returns. The documentation is too slim for me to tell, and I'd hate to have it turn into a rare crash in users hands.

I'm probably over thinking it. There's no way this object is large enough for there to be harm in it staying alive for the life of the view controller. It's not worth the effort to try to save this little bit of memory.
JasonR is offline   Reply With Quote
Old 02-11-2011, 01:21 PM   #12 (permalink)
Registered Member
 
Join Date: Dec 2009
Location: Brooklyn, NY
Posts: 74
Desdichado is on a distinguished road
Default

I struggled with this for a while too, but I'd guess that:

Code:
[alert show];
is just a friendly way of saying

Code:
[[[UIApplication sharedApplication] keyWindow] addSubview:alert];
And so as soon as you show it, the window is maintaining a reference to it, and you can release it. I always release alerts as soon as I show them, and I've never had an issue.
Desdichado is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 404
16 members and 388 guests
Brandt, coolman, fredidf, Free App Monster, givensur, iAppDeveloper, jbro, Kryckter, locombiano89, Mah6447, Meoz, simplymuzik3, SLIC, stevenkik, Tomsky, WeaselPig
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,646
Threads: 94,111
Posts: 402,862
Top Poster: BrianSlick (7,990)
Welcome to our newest member, locombiano89
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 05:51 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0