Objective-c coding - objective-c

I'm really confused about using proprieties.
if i declare this
#property (nonatomic, strong) NSString* aString;
what is the difference between this
1.#synthesize aString = _aString
and
2.#synthesize aString;
if i want to use it, what is the difference between:
3. anOtherString = aString;
and
4. anOtherString = self.aString;
and
5. anOtherString = _aString;
I know that the _aString is the ivar, but the problem is the combination between 1,2,3,4,5.
for example, if i use 2 and 4, i'm i passing a reference to anOtherString or a copy of it ?
I usually use 2 and 4 is that the best choice for passing a reference ?

Your answer are here :
1.#synthesize aString = _aString
Ans: Your property name is aString but you are making an alias _aString. Now you can access aString, your accessors can be used by _aString only. From Xcode4.4 onwards this statement comes by default.
2.#synthesize aString;
Ans: This is the basic style of Objective-c synthesizing a property. From Xcode4.4 onwards this statement overrides the above one.
3.anOtherString = aString;
You are accessing the property by the reference variable/alias.
4.anOtherString = self.aString;
You are using accessor to get its value.
5.anOtherString = _aString;
You are accessing the property itself.
I usually use 2 and 4 is that the best choice for passing a reference ?
Ans : This is good way to do, as self. makes your class KVC compliant.

When you use your #synthesize declaration, this generates getters/setters for you. When you use the #synthesize declaration #synthesize aString = _aString you are making it so that your getter/setter methods will use setAString and aString. You are creating a private variable called _aString. This means that inside your class, you can get this variable by calling
NSString *tempString = _aString;
or
NSString *tempString = self.aString;
The latter uses the generated getter method to retrieve aString.
You can also set your variable using the following methods:
_aString = #"";
or
self.aString = #"";
The latter uses the generated setter method. This is very important, because if you have declared your property as retain (now strong) or copy, then your setter method performs some logic that you may not be aware of (please review strong/copy/weak properties). Essentially, if you have a strong property and you use the generated setter, your code releases it's previous reference on that variable and creates a strong reference to what you're assigning to your variable.
I personally try to always use the getter/setter approach unless it's a weak reference (then it really doesn't matter). I usually always use the #synthesize aString = _aString approach as well, so that I can name method parameters aString if I choose. It helps avoid naming conflicts.
Please let me know if I can clarify in any way.

Related

custom class initializers with ARC - self.name or name?

when defining a Person class with ARC,
should i use self.fullname or just fullname in the initializer?
if i use fullname will the passed strings be retained?
if i use self.fullname i must define a setter or a property? should i use strong?
coming from a pre ARC way of thinking, i'm trying to wrap my head around the changes ARC suggests.
With ARC, these behave the same way, except that self.fullname will pass through the setter. The default setter will give you KVO-compliance. But otherwise, there is no difference.
Yes they will, if the pointers have been declared strong.
To use self.fullname = ... you must define a setter. For NSStrings and other classes which have mutable variants, it is usually recommended to use (copy).
In initializers, I'd advise against invoking any methods on self, because the object is in that unusual state where it lacks self-consistency. For the simple example you give, it doesn't make a difference right away. But if you later define your own -setFullname: method that reads or writes any other part of your object, invoking self.fullname = from your initializer will cause problems because the object isn't fully-formed yet.
I think the available answers need some clarification.
The long answer to your question
Look at this header:
Person : NSObject {
NSString *name; // better to call this _name to not confuse it with the property
// and even more better to not use an ivar, but only a property
}
#property (strong) NSString *name;
You have an instance variable. Usually you'd call your ivar the same as the property with an underscore, but often you'll find the ivar and the property have the same name.
It is also possible to only declare a property, in this case, the compiler will automatically insert an ivar with an underscore for you!
Now it is important to understand, that there is one major difference between name = #"John Smith" and self.name = #"John Smith", the first one directly sets the instance variable (aka _name = #"John Smith", disregarding memory management and (without ARC) creating a leak if the former value was not nil. Using the self-dot-syntax (self.name) uses the automatically generated accessor (=setter method), which respects the chosen memory management (typically retain or strong or copy).
Before properties and before ARC an object setter would have looked like this:
-(void)setName:(NSString*)newName {
if(newName != name) {
[name release];
name = newName;
[newName retain];
}
}
that means, the old iVar value is released and the new iVar value retained. All balanced and fine.
Now, with ARC and synthesized accessors (properties), you do not have to care about all this. While Properties synthesize acessors, ARC synthesizes and balanced retain/release calls based on an analysis of your code. So ARC and properties are not necessarily requiring each other, because they synthesize different aspects (note for example the different syntax "__weak" at the ivar declaration and "(weak)" at the property declaration?). But it's useful to know how it used to work, because now you'll see that there is a major difference between
name = #"John Smith"; // directly access ivar, the old value is never released
// your program is leaking if you're not using ARC
and going through the synthesized accessor
self.name = #"John Smith"; // old ivar released, new ivar set, all okay
The short answer to your question
do not use an ivar and a property if there is no need for both
self.property = newValue sets the new value by its setter method
ivar = newValue sets the new value directly, bypassing any setter method
it is definitely recommended to use the accessors and to not set ivars directly if there is a setter method (in other words: if you have a property, use its setter by calling self.property = newValue)

Again about getters and setters in objective-c

Here is my code
Class.h
#interface Class : NSObject
{
NSString *str;
}
#property (nonatomic, copy) NSString *str;
#end
#implementation Class
#synthesize str = _str;
-(void)someMethod
{
self.str = #"This is a string";
}
Here I can't figure out does self.str access str ivar directly or by getter and setter methods "generated" by synthesize directive ?
If you use self.str = … it's just syntatactic sugar around [self setStr:…]. So you are going through the setter method. Even if you get a value with self.str you are going through an accessor - which is useful to know if you are implementing lazily loaded properties.
you can only access the iVar directly in your case with _str because you've (correctly, In My Opinion) declared that to be the name of the backing store.
Edited to add
There is a problem with your example - you've defined the iVar str which isn't being used (the iOS uses a modern runtime where you don't need to declare iVars for properties that you synthesize). So although your code is writing to a backing store _str and that is the store that is being used through self.str if you were to access the str variable directly you would be using the declared iVar, not the one that you have a property for.
Your line
self.str = #"This is a string";
accesses the property. Your ivar is named _str.
If you had named them the same (ie not renamed the iVar to _str in your #synthesize line), self.str would still access the property while
str = #"This is a string";
would instead access the iVar. Considering how easy it is to mix those two up, renaming the iVar as you do is a very good habit.
As soon as you use "self.", you're accessing the property. If you would have accessed "_str", you would have accessed the ivar.
You won't access ivar str because property str refers to _str.
Use
#synthesize str;
to access ivar str via property
When you use self.something, you are using the property itself and not the instance variable. With this being said, it is also possible to create properties without having to worry about instance variables. Check out this post:
Objective-C Properties with or without instance variables

What does #synthesize variable = _variable really do? Is it very helpful?

I get that #synthesize-ing a variable automatically creates the accessor methods for the #property defined in my .h file and that using = _variable tells the compiler the name to use for my backing variable, but does it do anything else for me?
I have pretty much been assigning and reading from my class variables using something like
self.variableName = somethingElse
or
self.someLabel.text = self.someString
Could I instead (assuming all #synthesize statements are correct, etc.) do something like?
_variableName = somethingElse
Instead of using self.variable can I go around using _variable and not worry about it? Should I use [_variable release] in my dealloc or [self.variable release]?
I'm still confused on some of the why's of objective-c/cocoa/iOS development.
#synthesize varible1 is equivalent to #synthesize variable1 = variable1 -- It's saying that you're giving the instance variable and the property the same name.
When you say #synthesize variable1 = variable2, variable1 is the name of the property and variable2 is the name of the instance variable.
With the above #synthesize statement, if you say:
self.variable1 = something;
then, if the property has the "retain" attribute, the object something is retained (and any old object in variable1 is released).
But if you say:
variable2 = something;
Then no retains/releases occur. Most likely this will result in a lost object bug.
As to the release in dealloc, you can say either
[self.variable1 release];
or
[variable2 release];
Though the latter is preferred.
You can also say:
self.variable1 = nil;
This will release the variable and nil it.
But note that the first two forms should only be used in dealloc.
The reason to do it is this.
Say you are overriding an accessor in ARC. You write it like so:
- (void) setMyValue:(NSString *)myValue
{
_myValue = myValue;
}
If you had not done:
#synthesize myValue = _myValue;
You would have to re-name the argument coming in to not shadow your instance variable.
Also as the esteemed "Hot Licks" noted, if you leave the instance variable named myValue it's too easy to use it directly instead of the accessor, which means when you override that accessor it doesn't affect all the code it should.

Objective-C, interface declarations with properties

In the following common sample,
////
#interface MyObject : NSObject
{
#public
NSString * myString_;
}
#property (assign) NSString * myString;
#end
#implementation MyObject
#synthesize myString = myString_;
#end
////
why declare myString_ in the interface at all?
I ask because we can still get and set myString in the implementation using self.myString, [self myString], self.myString = ... and [self setMyString:...] and in fact we must if instead it's being retained.
This is a matter of preference/convention for some. By default, doing:
#property (assign) NSString * myString;
...followed by:
#synthesize myString;
...will give you three things. You get a setter method that can be accessed as self.myString = #"newValue" or [self setMyString:#"newValue"], a getter method that can be accessed as NSString* temp = self.myString or NSString* temp = [self myString], and an instance variable named myString that be be accessed directly inside of your class (i.e. without going through the getter and setter) and used to set and get the property value, and which is used internally to back the property.
If you like you can do #synthesize myString = someOtherVarName, and then you still get the setters and getters just as before, but instead of the myString instance variable the someOtherVarName instance variable is used to back the property, and no myString variable is created.
So why ever use the more verbose syntax? There is never any case that requires that you do so, but some people prefer to do so when dealing with properties that are declared retain or copy. The reason for this being that setting a property declared retain or copy via its generated setter method will affect the retain-count of the object being set/unset. Doing the same thing by accessing the instance variable directly will not.
So by aliasing the instance variable to something else, you can make a distinction in the code along the lines of "anything that does xxx.myString = Y is modifying the retain count, while anything that does someOtherVarName = Y is not". Again, it's not necessary to do this, but some people prefer to.
You should be able to skip it. Modern compilers allow that.
When you define a property, you are actually declaring how the getter and setter methods are constructed for a particular instance variable. Earlier it needed the instance variable to be defined so you declared it. It also allowed the property name to differ from the instance variable name via #synthesize myProperty = myIVar;. Now you don't need to do this as the modern compilers generate the instance variable for you.
The dot syntax is actually a convenience thing as you would've noticed. It doesn't directly refer to the instance variable but the methods myProperty and setMyProperty:. You can even call myArray.count where count isn't a property (I wouldn't recommend it even though lot of people seem to like it).
While there is a difference between the two, the gap seems to be slowly closing.
That's just a problem about point of view. If you access ivar directly, it's you're accessing it internally. If you're using property, you're not accessing ivar (semantically). You're using accessing method of the object. So you're handling the self as like external object which the internal is unknown.
This is encapsulation problem of Object-Oriented paradigm.
And I recommend some tricks when using properties.
The ivar declaration is optional, not required. Compiler will generate it automatically.
You should set the ivar as #protected or #private to encapsulate it correctly. (at least there is no reasonable reason)
I recommend to use nonatomic if you don't need threading lock when accessing the property. Threading lock will decrease performance greatly, and may cause strange behavior in concurrent execution code.
You can use this code to do same thing.
#interface MyObject : NSObject
#property (assign,nonatomic) NSString * myString;
#end
#implementation MyObject
#synthesize myString;
#end
And this will be transformed roughly something like this.
#interface MyObject : NSObject
{
#private
NSString* myString; // Ivar generated automatically by compiler
}
#end
#implementation MyObject
// Methods with thread synchronization locking generated automatically by compiler.
- (NSString*)myString { #synchronized(self) { return myString; } }
- (void)setMyString:(NSString*)newMyString { #synchronized(self){ myString = newMyString; } }
#end
In fact, I'm not sure about synchronization lock with assign behavior directive, but it's always better setting it nonatomic explicitly. Compiler may optimize it with atomic operation instruction instead of locking.
Here is reference document about the properties: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html%23//apple_ref/doc/uid/TP30001163-CH17
With the modern Obj-C runtime, declaring the ivar is more of a formality than anything else. However, there are some memory management things to keep in mind.
First, the property declaration for an object type is usually retain, or for strings it may be copy. In either case, the new object is retained.
Given the following code:
NSString *string = [[NSString alloc] init];
myString_ = string;
self.myString = string; // If the property was retain or copy
The second assignment would leak; the first would not. This is because the property would retain something that already has a retain count of 1—it is now at 2. When you release the property in dealloc, the count goes to 1, not 0, so it won't be released. With the first option, however, the retain count stays at 1, so dealloc brings it down to 0.
In your example, leaving the property as assign will make the ivar declaration a formality.

#property question

In my implementation I have getters and setters like below. I want to use properties and synthesize the getters and setters but have a few questions.
- (NSString *)title {
return title;
}
- (void)setTitle:(NSString *)value {
if(title != value) {
[title release];
title = [value retain];
}
}
If I was to convert that to a property, what attributes would I use? Am I right in thinking:
readwrite so both getters and setters are present
retain so that it increase the retain value of the value string so the object don't lose it.
Am I right with the above?
One final thing. I have the method below ...
- (void)setReleaseDate:(NSString *)value {
// YYYY-MM-DD HH:MM:SS +HHMM
if([releaseDate description] != value) {
[releaseDate release];
releaseDate = [[NSDate alloc] initWithString:value];
}
}
Am I right in thinking I still have to include that method because it contains code that the synthesized getter would not include?
Thanks.
For your title property, you can declare it in your class interface as follows:
#property (nonatomic, retain) NSString* title;
Which is the same as the following:
#property (readwrite, nonatomic) NSString* title;
readwrite is a default setting. Most of the time you will want setters for your properties, so for the times when you don't you would use the non-default readonly to specify this.
The nonatomic part basically means that the accessors will be faster, and is typically used. You can find out more information about this here: What does the property "Nonatomic" mean?.
For your second question, you can implement your own accessors if you wish. If you do this then it kind of 'overrides' the accessor that would be generated by Objective-C. Remember that you have to keep to the naming conventions. So in your example, the "setReleaseDate:" method you've defined would be used for the setter method for the property "releaseDate" - which is completely correct! :) The problem you have though is that you're passing an *NSString** to set the date, which means that this method won't override the default setter that would be used if you synthesized the property. You have to pass a value of the same type as the one you're setting as the single argument, so for this case you would have to pass an *NSDate**.
You must also ensure that if you provide your own implementation of an accessor that it does what is declared in the interface. I presume your releaseDate property should be declared as retain.
Your assertion about using readwrite as well as retain is correct as it would create semantically equivalent code to what you have posted.
The releasedate property setter can't be synthesized as you're transforming a NSString into a NSDate to store it, that also avoids common issues with NSString properties, for which you'd better use copy to avoid problems with NSMutableString.
Other than that, your code is fine, except that for string comparison you may want to replace the simple pointer check != with isEqualToString, see Comparing Strings in Cocoa.
It is common, though not always required, to use copy semantics for NSString properties, to avoid issues with NSMutableString objects being changed behind your back.
Otherwise, you seem to be pretty much on top of it.