Assigning ivars using self keyword in an object's init method - iphone

I've read that it's bad to use self.ivar = (convenience method) in and object's 'init' method, as this messes with inheritance.
However, if you know you're not going to subclass your object, is it ok to use the self keyword assignment?
i.e. self.iVar = [Object objectConvenienceMethod];
The reason I ask is this. I create a new object with its own init method, and in that method, I perform various initial assignments. Since I don't use the self keyword, I assign them directly to the iVars, and therefore use the alloc methods rather than the convenience methods. I.e.
iVar = [[Object alloc] init];
Or if I use a convenience method, I retain it. I.e.
iVar = [[Object convenienceMethod]retain]
But... when I run my program with the memory leak tool on, all of these assignments are identified as memory leaks.
If I can use the self keyword plus a convenience method instead of alloc-init, then this would avoid the problem.
If I choose to use the alloc-init approach though, where am I supposed to release the iVars?? Just in dealloc?
Thanks for your help :)
Michael

No, because it isn't only subclass behavior you need to take into account — superclass implementations and even the behavior of code generated by the framework (e.g. synthesized accessors and the black magic used to implement KVO) can also cause trouble. It will probably be OK, but that's still a significant chance of being not-OK. All in all, it's best just to follow Apple's recommendation and assign directly.
Assigning to ivars in init shouldn't be reported as leaks in a properly functioning program. If you're seeing that, there's some other problem that you need to address. Try reducing the problem to a minimal case that we can try out and ask about that — then we can tell what's wrong.

If you alloc or retain them in your class's init method, you should release them in the corresponding dealloc method.

I am thinking your "enclosing" class is not being released, and hence its dealloc method is not being called resulting in your iVars not being released.

Related

"Copy" when using ARC

I know that when using ARC and you have an NSString property, you do #property(nonatomic, copy) just as you would MRC. But I'm wondering, after I converted my project to ARC, I still have this in my initializer method:
_someString = [someStringParameter copy]
Is this a bug? Or even with ARC, do I still need to explicitly say "copy" ? Or should I just do:
self.someString = someStringParameter
and all will be OK? Bit confused here...
You'd never use self.someString = anything in your initialiser. The dot notation is a method call. You shouldn't call methods on classes that aren't fully instantiated yet. Most demonstrable failure case: a subclass overrides setSomeString: — where is it in its init when that method is called?
ARC will handle proper retains and releases on instance variables but can't automatically do copies — e.g. there are __strong and __weak modifiers but no __copy. So you still need explicitly to copy when doing a direct instance variable assignment.
_someString = [someStringParameter copy];
Is this a bug?
No.
Or even with ARC, do I still need to explicitly say "copy" ?
Absolutely.
You're assigning the instance variable by copy and it's perfectly legit under ARC. As opposed to that, doing just:
_someString = someStringParamenter;
will cause ARC to automatically retain (not copy) it, resulting in something like
_someString = [someStringParameter retain];
This happens because under ARC variables have an implicit __strong identifier unless specified otherwise.
self.someString = someStringParameter
This is right, and both under ARC and MRC you'll get the object to be copied if you provided the copy attribute in the property declaration.
That said, it's still a bad idea to use accessor methods in initializers, since they may have unwanted side effects in case you have a custom implementation for them. Check out this answer on the subject: Should I refer to self.property in the init method with ARC?

should I always use self.classvariable?

When coding my iPhone app. Is it always a good practice when setting or getting values to use self? I seem to forget half of the time and recently have been tracking down a bug I believe is related to this.
Should I ALWAYS use self or are there cases when it's not necessary or would cause problems?
Edit:
Here's an example of what I'm doing in the code
else if([CellIdentifier isEqualToString:#"Linked Item"]) {
linkedItemLabel = [[UILabel alloc] initWithFrame:CGRectMake(120, 5, 160, 34)];
linkedItemLabel.adjustsFontSizeToFitWidth = YES;
linkedItemLabel.textColor = [UIColor blackColor];
linkedItemLabel.font = [UIFont systemFontOfSize:17.0];
linkedItemLabel.text = [storedValuesMutableArray objectAtIndex:7];
linkedItemLabel.backgroundColor = [UIColor clearColor];
linkedItemLabel.textAlignment = UITextAlignmentRight;
[cell addSubview:linkedItemLabel];}
This is part of the code that sets up my tableviewcells for a form that needs to be filled. Should I be using self.linkedItemLabel or is this fine?
You have to understand that using self.property is a method call (getter or setter method), not a simple assignment.
You should use the ivar directly only inside the setter or getter body.
Reasons:
1/ Properties are meant to shield you from the retain-release hell. Let's imagine you have a "assign" property, you are using the ivar directly and then you decide changing it to "retain". What you get is a bug difficult to find.
2/ Setters and getters can do additional functionality (e.g. setter can add/remove observers to an object) or logging. If you are using the ivar directly you miss this special functionality.
3/ Setters and getters can be overriden in a subclass.
In small projects you can probably avoid most problems even if you are using ivars directly but on big projects, programmed by a team, you should use only self.property to reduce bugs and improve code maintainability.
It's also a good idea to give your ivar a different name (like property_ or _property because you'll notice when you are using it without self..
If you are not writing a high performance game or mathematic algorithms, don't worry about worse performance when using self.property.
It depends on the case, if you are just using #synthesize to auto-generate the getters, then it would not cause any problems on the getters. Although common OO practices tell you to use encapsulation, you will notice pretty much all apple sample code accesses the ivar directly.
Another common practice to refer to the ivar without using self is to synthesize like this:
#synthesize myVar=_myVar
and use _myVar when referring to that variable.
It would only cause a problem, if you implemented something in your getter, instead of using #synthesize.
As for the setters, it isn't exactly a problem, but you just have to keep in mind that the properties for that ivar will only be applied if you do self.myIvar as opposed to accessing the iVar directly, so for example a property declared as (retain), will only be retained if you do self.myIvar = newValue as opposed to myIvar = newValue.
The issue arises with properties. if you do not add the self., then you end up assigning to the variable directly, missing out on the property attributes e.g. retain, assign and thus messing up reference counting for the item, and thus causing potential memory leaks.
You should use self, unless you have an explicit reason not to.
You must use it with clever and clear understanding.
If you're using so-called dot-syntax (i.e. self.myVariable) it means you're calling a getter or setter of the property, which is actually a selector sending to an object instance, which is pretty heavy within Objective-C run-time. So, if you need just a value of your var - you can call it once and reuse saved state or call directly to i-var (if permissions allow).
Call for getters/setters when you really need them.

Why not use self. call inside class

I've read google's and apple's code guide, they both access instance variables without self. call(getter and setter) inside the method implementation even though they have declared a property for that instance variable.That's why?
In my opinion, using self. call to set and get instance variables inside the method implementation of class makes it easier to manager retain count.
Is there any caveat to use getter and setter inside class?
It depends. You should always use the accessor in normal use.
However for init and dealloc methods, you should instead use the direct ivars to release and set variables. That's because the setters can have side effects that are not good to trigger during class initialization or deallocation.
In practice using an accessor as part of init probably will not cause an issue. But I have seen a number of real world crashes where a custom setter was not expecting nil and so use of the accessor in dealloc crashed the app. Even if it didn't crash it could be doing a lot of pointless work since the class was about to die.

difference between assigning between self. and assigning from ivar directly [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When to use self on class properties?
Difference between self.ivar and ivar?
I know that when you do
self.array = [[NSMutableArray alloc] init];
this means that I am calling the setter method.
However, I can also do:
array = [[NSMutableArray alloc] init];
Which is assigning the ivar directly, no setters is called (I assume).
Sometimes both cases will have the same effect, sometimes not.
So what is the crucial main difference between doing one over the other?
Can someone explain this clearly..
If array property is retained then 1st one will cause a memory leak. In that case you are gaining ownership twice in one line, one via alloc and one via retained property. So one release is not enough.
And in 2nd one if you release immediately after alloc then you loose the ownership immediately as you have not retained array in that case.
The crucial difference is that the setter can have additional side effects — such as retaining the argument or issuing KVO notifications — while a simple assignment can't.
The Objective-C Programming Language tells you to use direct access in the initializer:
There are several constraints and conventions that apply to
initializer methods that do not apply to other methods:
If you set the value of an instance variable, you typically do so
using direct assignment rather than using an accessor method. Direct
assignment avoids the possibility of triggering unwanted side effects
in the accessors.
and in dealloc:
Typically in a dealloc method you should release object instance
variables directly (rather than invoking a set accessor and passing
nil as the parameter), as illustrated in this example:
- (void)dealloc {
[property release];
[super dealloc];
}
to avoid, as Chuck said, side effects like KVO notifications.
Example: in my code I have a variable that triggers the preloading of related data in advance. Sometimes I release it or set it to nil to get rid of the variable, which means I don't need to preload anything, so I use direct access. This example is rarely the case, but it doesn't cost you anything to follow this convention.

Would it be correct/ellegant use only alloc without init?

If we don't want to implement init method in our class, and bearing in mind that init in NSObject only returns an instance of the object without initialization, I don't see the point of calling init if we already get the instance with alloc. I have tried and it works, but I am not sure it won't cause future problems.
myClass *newObject = [myClass alloc];
instead of:
myClass *newObject = [[myClass alloc] init];
Thanks a lot.
No, just calling alloc would not be correct. alloc zeroes out all instance variables of the object, init then has the chance to set all or some instance variables to their default values. Some classes even use their init methods to create another instance and return that one instead of the one you allocated.
Many classes expect that their init methods get called and would possibly cause crashes if you don't call init. If you are talking about a custom class that inherits directly from NSObject and needs no initialization of instance variables, you might get away with [myClass alloc] but it is definitely not good programming style.
I think that it is not a good idea.
Read Cocoa Design Pattern, especially the "Two stage creation"
You can also read this article http://www.informit.com/articles/article.aspx?p=1398610
I think that it wouldn't matter much if you didn't implement a "- (id)init" because if you did, you would call NSObject's init method which just returns the same value you send to the method. Though it is a good idea to create your own init method to set your instance variable.
in runtime source code
perform -(id)init will call _objc_rootInit(self) and will return self. I guess only perform init is OK。