Objective-C Memory Management: crash on release

北城余情 提交于 2019-12-31 05:14:17

问题


I'm new to Objective-C and can't seem to get the memory management code right. I have the following code:

Media* myMedia = [self.myMediaManager getNextMedia];

self.navigationItem.title = [self.myMediaManager getCategory];
[self.btnImage setImage:myMedia.imageFile forState: UIControlStateNormal];
[self.lblImage setText:myMedia.imageLabel];

//[myMedia release];

My app crashes if I uncomment the above line. Do I need to do something special when I instantiate myMedia?

EDIT:

If myMediaManager is supposed to release it, when would it do that. Here is my code for getNextMedia:

- (Media*) getNextMedia {

    DLog(@"Start");

    Media* nextMedia = [[Media alloc] init];

    [self setNextMediaIndex];

    if (self.mediaIndex > -1)
    {
        nextMedia = [mediaArray objectAtIndex: self.mediaIndex];
    }

    return nextMedia;
}

EDIT2: I fixed the crashing issue (I was releasing an object I didn't own). I still see leaks and can't seem to find what the issue is.


回答1:


Only objects that you own can be released.

You can release objects if you new, alloc, copy, mutableCopy or retain them first.

Since there is no alloc/copy/retain in [self.myMediaManager getNextMedia]; you can't release it.




回答2:


Since myMedia is not retained here, you don't need to release it. When the origin (self.myMediaManager) releases it, it gets destroyed immediately.

NSString *string = [[NSString alloc] init];
[string release]; // now we have to release the string, since we allocated it.

NSString *string = self.navigationItem.title;
// now we don't, since it's a property of `navigationItem` and we didn't retain it.



回答3:


At this point, since you are just learning, you should probably just start off using ARC with the iOS5 beta versions of XCode. It's good to have an understanding but using ARC will save you many potential pitfalls - by the time you learn enough to produce something iOS5 will be out. You can still build applications targeting iOS4, so you'll still be able to reach a lot of people.




回答4:


The general rule for memory management is as follows:

For every retain, alloc, copy, or new, you need to call release or autorelease.

Since you did not call any these, you do not need to release myMedia.

For more information, take a look at this other answer I posted that deals with the subject. Also, since you are new to iOS development, I suggest looking at this answer as well.




回答5:


This updated code is suspicious:

Media* nextMedia = [[Media alloc] init];

[self setNextMediaIndex];

if (self.mediaIndex > -1)
{
    nextMedia = [mediaArray objectAtIndex: self.mediaIndex];
}

Depending on the condition in the if() clause, you assign a new value to nextMedia, which makes the value you just allocated unreachable, i.e. it can't be released.

Also, you don't retain the value you get from the array, so you should not release it either. But if the if() clause does not run, you still have the instance you alloc-ed, and that should be released.

That is not good. Try:

Media* nextMedia = [[Media alloc] init];
[self setNextMediaIndex];
if (self.mediaIndex > -1)
{
    [nextMedia release];
    nextMedia = [[mediaArray objectAtIndex: self.mediaIndex] retain];
}

You could also do (and I would prefer that):

Media *nextMedia;
[self setNextMediaIndex];
if (self.mediaIndex > -1)
{
    nextMedia = [[mediaArray objectAtIndex: self.mediaIndex] retain];
}
else
{
    nextMedia = [[Media alloc] init];
}

Now you can release nextMedia when that is not needed anymore, without any ambiguity about the retain count.



来源:https://stackoverflow.com/questions/7057721/objective-c-memory-management-crash-on-release

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!