Understanding memory management in ios

孤人 提交于 2019-12-12 03:17:09

问题


I am in the process of learnig objective-c and programming an iPad app. One thing I keep tripping myself up on and having to re-read is memory management. I am getting there...slowly. Basic rules such as for every alloc / retain you must have a release is useful. However, one relatively basic thing eludes me and I wonder if someone could explain...

Take the following code...

NSArray *myArray = [[NSArray alloc] init];
myArray = [someNSSet allObjects];

This is relatively straight forward coding and would require a [myArray release] statement.

However, I keep seeing examples of (and indeed, I have used extensively the following 'short cut'...

NSArray *myArray = (NSArray *)[someNSSet allObjects];

How, as far as I understand when you use the (NSString *) you dont need to use a [myArray release] statement, but I dont understand why.

Could someone possible explain?


回答1:


In the first line:

NSArray *myArray = [[NSArray alloc] init] 

some amount of memory is allocated for an array (actually in this case it is senseless since the size of the array is 0. Keep in mind that NSArray is immutable!). The variable myArray holds the address of the first byte of the reserved memory area.

Now in the second line you change the value of myArray which now will point to the first byte of the memory area where [someNSSet allObjects] is stored. At this moment you do not know any more where the array is stored what you've created in the first line. And so you have a leak.

The line:

NSArray *myArray = (NSArray *)[someNSSet allObjects];

is correct, since you do not reserve any memory at this point. If you are not using ARC you might call retain in order to keep GC away from the referenced block of memory. In other way you might receive a BAD_EXEC when the owner of the object releases it and you try to access it through e.g.: [myArray objectAtIndex:0]




回答2:


NSArray *myArray = [[NSArray alloc] init];
myArray = [someNSSet allObjects];

this code is leaking myArray because you lose the reference to NSArray that you've allocated on the first line; you don't need to alloc here, because on the second line you're assigning a new value to myArray.

NSArray *myArray = (NSArray *)[someNSSet allObjects];

and this code example is perfectly fine, you're assigning the result of [someNSSet allObjects] to myArray pointer and you don't own the returned value, so you don't need to care about releasing it.

Consider using ARC (Automatic Retain Counting) for you project. With ARC the compiler takes care of retain counts so you don't have to, in fact aren't allowed to. There is a refactoring that will convert a current project.




回答3:


As you said, there is a leak in the first code you posted. so you must add a release:

NSArray *myArray = [[NSArray alloc] init];
[myArray release];
myArray = [someNSSet allObjects];

In fact, when you obtain an object through a method that starts with alloc, new or copy, you own it, and you should release it. That's why, here you should release the array you obtained using the method alloc. This convention makes it easy to know when you own objects and when you don't. So remember: alloc, new or copy.

As for the second example, you obtained the array though a method that doesn't start with one of the three words (alloc, new or copy), so you don't own the object, and you are not responsible of releasing it. In fact, the array you obtained is an autoreleased object, which means that even though its retain count is currently 1, it will be automatically released when something called the autorelease pool is drained.

Here is a reference about Memory Management Rules.



来源:https://stackoverflow.com/questions/9455797/understanding-memory-management-in-ios

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