Why [self.property release] will cause the static analyzer to display the error "incorrect decrement of reference count"?

Possible duplicate:
Incorrect decrement of reference counting of an object that is not currently owned by the caller
Why shouldn't I use getter to release a property in objective-c?

So, I understand that using [self.myProperty release] not recommended (Apple itself recommends not doing this). Although it seems to me that it CAN lead to problems in some cases, and not to all cases. It's right? More importantly: I don’t understand why using syntax like [self.myProperty release] in my -dealloc method will cause the static analyzer to show an "incorrect decrement" error. Despite any other reason discouraging such syntax, my class still owns its properties (which I declared using "nonatomic,retain" ), so why a warning?

I read a few posts about this, but it seems like I can't think it over. Some of them describe in detail the possible side effects of using this syntax, but what I really want to know is the cause of the “incorrect decrement” error.

Any help would be greatly appreciated.

+2
source share
3 answers

Cocoa Memory Management has the concept of "ownership", which is most concisely expressed in the rule: if you call new or alloc or send retain or copy to an object, you own the result and are responsible for sending release when you are done with it. Otherwise, you do not own it, and you should not send release .

Instance variables, basically by definition, contain objects that the instance owns. You need the objects to be valid for the life of the instance, so you create them using the method of granting ownership in init :

 // myDinkus and creationDate are ivars of whatever class this is. // They are assigned to with owned references. myDinkus = [[Dinkus alloc] init]; // ownership due to alloc creationDate = [[NSDate date] retain]; // ownership due to retain 

Now they need to be sent release when the instance is done with them; generally speaking, it will be in dealloc .

Getter methods do not return owner references. So it should be so; when your code, for example, asks for a label for the font color, it does not need this colored object. Or, if so, he should explicitly take responsibility by sending retain . Providing them with default ownership would create headaches at best, and possibly leaks.

It is established that [self.myProperty release] makes the static analyzer complain, because it is a violation of the concept of ownership. The object returned from [self myProperty] does not belong to the caller. The fact that he simply turned out to be the same object as an ivar belonging to the caller does not matter. (Actually, it may not be the same thing: a getter can return a copy of the object that it represents, for example. It can build a completely new value based on a group of Ivars. It is even possible that there is no ivar, it matches the getter.)

Since objects that do not belong should not be sent release , so the result of the getter result is incorrect.

There are other, practical reasons for not doing this (good enough, especially Justin to answer in a question suggested as a hoax), but that the analyzer complains about the reason.

+4
source

Essentially, you are sending a release message to an object that you have not yet sent retain (at least not explicitly). The static analyzer expects to see balanced save / release.

+1
source

When you declare your property as nonatomic,retain , you are responsible for releasing the value for the property adjuster.

If you execute [self.myProperty release] , then your property still contains its old value, and any subsequent setting of this property will release according to this old value - but you already released it, so now it is overloaded, released .. Therefore, a warning.

To free the value that you must use self.myProperty = nil , the installer self.myProperty = nil old value and sets this property to nil .

+1
source

All Articles