Re: How is this an "incorrect decrement of a reference count"?
Re: How is this an "incorrect decrement of a reference count"?
- Subject: Re: How is this an "incorrect decrement of a reference count"?
- From: Eeyore <email@hidden>
- Date: Mon, 19 Mar 2012 06:51:22 -0700
First, what Roland said. In addition to that, keep in mind that when you code
self.imagePicker = aPicker;
...
anotherPicker = self.imagePicker;
it is best to assume that aPicker and anotherPicker are different objects (even if ... is empty, there may be other threads, or the setPicker code may do something unexpected with its input). Roland's temp variable is safe, using temp, you know you will be releasing the object you allocated, the one you own. With the code above, you lose the one you own and then release its doppelgänger instead.
Aaron
On Mar 19, 2012, at 6:18 AM, Roland King <email@hidden> wrote:
> No, the analyzer is right and your code is somewhat confused. I'm trying to figure out how you ended up with code like that, did you find you had an extra retain somewhere and need to get rid of it? Again you are misunderstanding ownership.
>
> @property( nonatomic, retain ) UIImagePickerController *imagePicker;
>
> What does that mean? That means that you have a property which is a UIImagePickerController and when it's *set* with either [ object setImagePickerController:ipc ] or self.imagePickerController=ipc, the syntactic sugar for the method call, ipc is retained. The 'retain' is for the setter, not the getter.
>
> That's all it tells you, ie somewhere you either have
>
> @synthesize imagePickerController=_imagePIckerController;
>
> or
>
> -(void)setImagePickerController:(UIImagePickerController*)imagePickerController
> {
> [ imagePickerController retain ];
> [ _imagePickerController release ];
> _imagePickerContoller=imagePickerController;
> }
>
> -(UIImagePickerController*)imagePickerController
> {
> return _imagePickerController;
> }
>
> and
>
> -(void)dealloc
> {
> [ _imagePickerController release ];
> }
>
>
> Look at the getter, that doesn't retain imagePickerController, so the getter returns an object *the caller does not own*.
>
>
> So looking at the second piece of your code, it's basically equivalent to this (I will use the setXXX: method instead of the dot syntax, it's clearer, they are equivalent).
>
> UIImagePickerController *temp = [ self imagePickerController ];
> [ temp release ];
>
> but the analyser knows that [ self imagePickerController ] returns an object which the caller doesn't own, so you should not release it. self.imagePickerController is *NOT* the same as the ivar, it's a method which returns an object you don't own (the method name doesn't have new, copy or init in it).
>
> So what should you have done. Let's break the first piece of code down too into an equivalent
>
> UIImagePickerController *temp = [ [ UIImagePickerController alloc ] init ];
> [ self setImagePickerController temp ];
>
> temp is an object you do own, so you need to release. Ignore the fact that you pass it to a method (setImagePickerController:) which retains it, you don't care, you don't have to care, not your problem, if that method wants to retain it, up to that method. What you then need to balance this out is
>
> [ temp release ];
>
> Or if you want to do the assignment in one line, you have this version
>
> [ self setImagePickerController:[ [ UIImagePickerController alloc ] init ];
>
> ok the problem there is that [ [ UIImagePickerController alloc ] init ] returns an object you own but you haven't assigned it to anything you can release after the property setter call. This is where autorelease would help you, it will release the object but only sometime after the property setter
>
> [ self setImagePickerController:[ [ [ UIImagePickerController ] alloc ] init ] autorelease ];
>
>
> [ self.property release ] or [ [ self property ] release ] is plain wrong, even if it happens to be working because you happen to be returning your underlying ivar which happens to have an 'extra' retain on it. The analyser is right, don't do that. I'd expect it to complain about all such calls, you really have the same construct in them all, [ self.someproperty release ]?
>
> So replace this
>
> self.property = [ [ AnObject alloc ] init ];
> [ self.property release ];
>
> with either
>
> AnObject *temp = [ [ AnObject alloc ] init ];
> self.property = temp;
> [ temp release ];
>
> or
>
> self.property = [ [ [ AnObject alloc ] init ] autorelease ];
>
>
>
> On Mar 19, 2012, at 8:18 PM, G S wrote:
>
>> I have this in my header file:
>>
>> *
>>
>> **
>>
>> @property (nonatomic, retain) UIImagePickerController* imagePicker;
>> **
>>
>> *
>> The analyzer is complaining about lines like this (but not always):
>>
>> *
>>
>> self.imagePicker = [[UIImagePickerController alloc] init];
>>
>> [self.imagePicker release];
>>
>> *
>> I do this in many places, but in a few of them the analyzer says:
>>
>> *Property returns an Objective-C object with a +0 retain count*
>> *Incorrect decrement of the reference count of an object that is not owned
>> at this point by the caller*
>>
>> Is this just a bug in the analyzer? I can find no difference between the
>> times it makes this complaint and the many more times that it doesn't.
>>
>> Thanks for any insight.
>> _______________________________________________
>>
>> Cocoa-dev mailing list (email@hidden)
>>
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>>
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>
>
> _______________________________________________
>
> Cocoa-dev mailing list (email@hidden)
>
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>
> Help/Unsubscribe/Update your Subscription:
>
> This email sent to email@hidden
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden