开发者

When to release UIImage and NSString Resources

开发者 https://www.devze.com 2023-02-20 19:46 出处:网络
I\'m trying to get my memory management right and in the code below, if I include the final release statement (the one for filePath), it crashes and I can\'t see why.I\'ve alloc\'ed it, so why shouldn

I'm trying to get my memory management right and in the code below, if I include the final release statement (the one for filePath), it crashes and I can't see why. I've alloc'ed it, so why shouldn't I release it?

Further down, I return cellAbout to the TableView.

Can someone explain?

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
filePath = [filePath stringByAppendingString:@".png"];
UIImage *image = [[UII开发者_如何学Cmage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];
[filePath release];

Many thanks,

Chris.


The answer is that the original filePath string IS alloced and needs to be released, but when you have the line:

  filePath = [filePath stringByAppendingString:@".png"];

you create a different string - the original pointer to filePath is now gone and is a leak.

Here is the code you actually want

 NSString *filePath = self.gem.poiType;
 filePath = [filePath stringByAppendingPathExtension:@"png"];
 UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
 imageView.image = image;
 [image release];

So you don't need to release the filePath - it is auto released. Also apple has a special call for adding path extensions.

 NSString *filePath = [self.gem.poiType stringByAppendingPathExtension:@"png"];

is actually how most people would write that code - one fewer lines.


Your Issues

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];

Leaking filePath after this line.

filePath = [filePath stringByAppendingString:@".png"];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: filePath];
imageView.image = image;
[image release];

Releasing an autoreleased object after this line.

[filePath release];

Instead

UIImageView *imageView = (UIImageView *)[cellAbout viewWithTag:2];
NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
NSString *extendedFilePath = [filePath stringByAppendingString:@".png"];
[filePath release];
UIImage *image = [[UIImage alloc] initWithContentsOfFile: extendedFilePath];
imageView.image = image;
[image release];


[NSString stringByAppendingString] returns a NEW string, so that's where you're leaking your old one.

And then filePath is no longer owned by you, so when you release it later, you crash.

You could sidestep this whole thing like this:

NSString *filePath = [NSString stringWithFormat:@"%@.png",self.gem.poiType];// don't release me.


You are leaking here and later releasing an autoreleased string:

filePath = [filePath stringByAppendingString:@".png"];

If you really want to manually release, save the pointer:

NSString *filePath = [[NSString alloc] initWithString:self.gem.poiType];
NSString *somestring = [filePath stringByAppendingString:@".png"];
[filePath release];
0

精彩评论

暂无评论...
验证码 换一张
取 消