Properties and Instance Variables in Objective-C - objective-c

I'm rather confused about properties and instance variables in Objective-C.
I'm about half-way through Aaron Hillegass's "Cocoa Programming for Mac OS X" and everything is logical. You would declare a class something like this:
#class Something;
#interface MyClass : NSObject {
NSString *name;
NSArray *items;
Something *something;
IBOutlet NSTextField *myTextField;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSArray *items;
Since other objects need to manipulate our name and items instance variables, we use #property/#synthesize to generate accessors/mutators for them. Within our class, we don't use the accessors/mutators—we just interact with the instance variable directly.
something is just an instance variable that we're going to use in our class, and since no one else needs to use it, we don't create a pair of accessors and mutators for it.
We need to interact with a text field in our UI, so we declare an IBOutlet for it, connect it, and we're done.
All very logical.
However, in the iPhone world, things seem to be different. People declare properties for every single instance variable, declare properties for IBOutlets, and use accessors/mutators to interact with instance variables within the class (e.g. they would write [self setName:#"Test"] rather than name = #"Test").
Why? What is going on? Are these differences iPhone-specific? What are the advantages of declaring properties for all instance variables, declaring properties for IBOutlets, and using accessors/mutators within your own class?

In the iPhone world, there's no garbage collector available. You'll have to carefully manage memory with reference counting. With that in mind, consider the difference between:
name = #"Test";
and
self.name = #"Test";
// which is equivalent to:
[self setName: #"Test"];
If you directly set the instance variable, without prior consideration, you'll lose the reference to the previous value and you can't adjust its retain count (you should have released it manually). If you access it through a property, it'll be handled automatically for you, along with incrementing the retain count of the newly assigned object.
The fundamental concept is not iPhone specific but it becomes crucial in an environment without the garbage collector.

Properties are used to generate accessors for instance variables, there's no magic happening.
You can implement the same accessors by hand.
You can find in Aaron Hillegass's book examples of 3 memory management strategies for member variables. They are assign/copy/retain. You select one of those as required for given variable.
I assume you understand memory management in Objective-c ...
Accessors hide the complexity and differences of memory management for each variable.
For example:
name = #"Test"
is a simple assignment, name now holds reference to NSString #"Test". However you could decide to use copy or retain. No matter which version of memory management you chose accessor hides the complexity and you always access the variable with (or similar):
[self setName:#"Test"]
[self name]
Now setName: might use assign/copy or retain and you don't have to worry about it.
My guess is that iPhone tutorials use properties to make it easier for new developers to jump through memory management (even though it's handy to generate appropriate accessors with properties rather than implement them by hand every time).

However, in the iPhone world, things seem to be different. People declare properties for every single instance variable, declare properties for IBOutlets, and use accessors/mutators to interact with instance variables within the class (e.g. they would write [self setName:#"Test"] rather than name = #"Test").
That's not iPhone-specific. Except in init methods and the dealloc method, it's good practice to always use your accessors. The main benefit, especially on the Mac (with Cocoa Bindings), is that using your accessors means free KVO notifications.
The reason why people “declare properties for every single instance variable” is most probably that all of their instance variables are things they want to expose as properties. If they had something they would want to keep private, they would not declare a property for it in the header file. (However, they may make a property for it in a class extension in the implementation file, in order to get the aforementioned free KVO notifications.)
Declaring properties for outlets is overkill, in my opinion. I don't see a point to it. If you don't make a property, the nib loader will set the outlet by direct instance-variable access, which is just fine for that task.

I would suggest that modern development has made a very strong attempt to identify, define and apply best practices.
Among these best practices we find continuity and consistency.
Apart from arguing over use of accessors in init and dealloc methods, accessors should generally be used all the time (inside and outside of a class) for the benefits they offer, including encapsulation, polymorphic var implementations (which both allow for abstracting and refactoring) and to facilitate those best practices of continuity and consistency. The fundamental benefits of an object-orient language come into play when doing things in this way and exploiting the fullness of the language's capabilities. Always being consistent in one's coding is an oft undermentioned benefit, as any senior programmer will usually attest.

You can write like this
//MyClass.h
#class Something;
#interface MyClass : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSArray *items;
#end
//MyClass.m
#interface MyClass()
#property (nonatomic, strong) IBOutlet NSTextField *myTextField;
#property (nonatomic, strong) Something *something;
#end

Related

Questions about instance variable, properties, implementation and interfaces

I have been programming for the iOS platform for the last few years but mainly using swift. In the recent months though, I have been tasked with a project using Objective C, and while I like it and found it easy to learn, there are some questions mainly about variables that I still don't quite understand.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
2) What is the difference between declaring variables in the #implementation or properties #interface inside the .m file?
From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
4) Whenever I declare two instance variables with the same name in the #implementation in two different classes I get a "duplicate symbol" error. Why does this happen?
Just another simple question out of curiosity:
I see many questions where in the code the #interface has curly braces, but in my code I've never seen it, rather it ends with a #end like the #implementation file. Was this in earlier versions of Obj-C or is there any real difference?
Thank you so much, I know these are 4 or 5 questions, but I jumped so quickly into a project and I think I really need to learn the basics, which I skipped because I could not find answers to this questions.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
A property may or may not be backed by an instance variable. By default they are but you can declare a property and the explicitly provide both a getter and setter (if not read-only). Then the property will not have an implicitly declared ivar. Properties make it easy to indicate whether it is atomic or not, whether it is read-only or not, and it lets you indicate the memory management (strong, weak, copy, assign). Properties also provide support for key-value observing.
If you want a simple variable used privately without the need for any of those features, then a direct ivar without a property is over so slightly more efficient.
See Is there a difference between an "instance variable" and a "property" in Objective-c? for more details.
2) What is the difference between declaring variables in the #implementation or properties #interface inside the .m file? From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
The private #interface Whatever () in the .m is known as the class extension. It's basically a special unnamed category. There is no difference between declaring ivars there or in the #implementation block.
Personally I use the class extension to privately conform to protocols and to declare private properties. I use the #implementation block to declare private ivars.
Variables in the #implementation block are normal instance variables if they are put in the curly braces.
#implementation {
// ivars here
}
// variables here are globals. Same as before #implementation or after #end
// methods
#end
Without the curly braces those variables become globals.
See Difference between variables in interface Object() {} and #implementation Object #end and Difference Between Declaring a Variable Under #Implementation And #Interface Under .m file for more details.
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
Atomic properties are not really thread safe. It just means the assignment is atomic and a read is atomic but it doesn't really mean thread safe in the broader sense.
See What's the difference between the atomic and nonatomic attributes? for a much more thorough discussion.
4) Whenever I declare two instance variables with the same name in the #implementation in two different classes I get a "duplicate symbol" error. Why does this happen?
See #2. You must not have your variables in the #implementation block curly braces. Put the variables where they belong and the problem goes away.
If you actually want the variable to be a file static, put it before the #implementation to make it clear that it isn't part of the class and prefix the variable declaration with static. Then if you happen to have two with the same name in different files, there won't be a duplication problem if they are static.
1) What is the difference between declaring an instance variable and a property? Since the compiler automatically creates an instance variable for every property, is there any real advantage besides being able to pass in some parameters like atomic, nonatomic, strong, weak, assign, etc?
Properties are really just methods wrapped in a syntax. They're intended to be called by other classes, assuming they're publicly provided. Instance variable is more like a field access in C. You should probably default to using properties (they support KVO, are safe on nil, etc.). You should certainly default to using properties for getting/setting, except possibly in the initializer.
Note, though, that the compiler does not always create instance variables. If you provide both getter and setter, you'll need to tell it to with #synthesize foo=_foo;.
2) What is the difference between declaring variables in the #implementation or #interface inside the .m file? From what I understand, declaring in the #implementation makes it a static variable and declaring it in the #interface makes it an instance variable, is that correct? Also why do classes that inherit from UIViewController (for example) already have an #interface in the .m file and classes that inherit from NSObject don't?
Historically, instance variables could only be defined in the #interface.
3) (Personal Question) Do you usually set a property to be atomic or nonatomic? I find that atomic is better because while it may be slower it is thread safe, but I see most people using nonatomic. Is the speed difference still noticeable nowadays with the amount of power we have?
The reason for using nonatomic is that atomic doesn't really solve thread safety as much as you'd think. For example, this is still thread unsafe, even if the property is set to atomic (since the value of foo could change between the read and write):
self.foo = self.foo + 1;
For this reason I think most favor nonatomic and handling thread safety specifically when needed.

Objective-C property attributes best practices

After multiple searches and reads about property attributes, I still can't understand them completely and create a reflex of using them correctly.
I have multiple questions:
1) What does a default attribute mean?
As I understood, not specifying an attribute in a "group", the default one is used, so this:
#property NSString *string;
is atomic, right?
By this logic, this article says that strong and assign are defaults, so if I have:
#property (nonatomic) NSString *string;
is the string property strong or assign?
How are the available attributes "grouped"? Or as Xcode words this, what attributes are mutually exclusive?
2) Are there any generic rules that one should follow?
For example, I saw one comment that said that you should use copy for classes with mutable variants like NSString, NSArray.
And another one that said that you should use assign for C objects.
So, is it a good idea to always use:
#property (copy, nonatomic) NSString *string;
#property (assign, nonatomic) CGFloat float;
?
What other standard practices exist for property attributes?
3) What problems could arise if I use "wrong" attributes? What if I just use nonatomic for all the properties in a project?
1a) The default attributes for a property are atomic, and strong (for an object pointer) or assign (for a primitive type), and readwrite. This assumes an all ARC project.
So #property NSString *string; is the same as #property (atomic, strong, readwrite) NSString *string;. #property int value; is the same as #property (atomic, assign, readwrite) int value;.
1b) Attributes are grouped as follows:
atomic/nonatomic
strong/weak/assign/copy
readwrite/readonly
Pick one and only one from each of those three groups.
Actually, the latest Objective-C adds support for nullable/nonnull with the default being nullable.
2) General rules are as you say.
Object pointers should usually be strong.
Primitive types should be assign.
weak should be used in child/parent references to avoid reference cycles. Typically the parent has a strong reference to its children and the children have a weak reference to their parent. Delegates are typically weak for the same reason.
copy is typically used for NSString, NSArray, NSDictionary, etc. to avoid issues when they are assigned the mutable variant. This avoids the problem of the value being changed unexpectedly.
There's a big "gotcha" using copy with NSMutableString, NSMutableArray, etc. because when you assign the mutable value to the property, the copy attribute results in the copy method being called which gives back a non-mutable copy of the original value. The solution is to override the setter method to call mutableCopy.
3) Using the wrong attribute could have serious problems depending on the needs of the property and the attribute being used.
Using assign instead of strong for an object pointer is probably the worst mistake. It can lead to app crashes due to trying to access deallocated objects.
Using nonatomic instead of atomic on a property that will be accessed concurrently on multiple threads may lead to really hard to find bugs and/or crashes.
Using strong instead of copy for NSString or NSArray (and other collections) can possibly lead to subtle and hard to find bugs if mutable variants were assigned to the property and other code later modifies those values.
#rmaddy's answer is a good one.
I would add the following.
If you are creating (or have inherited) classes that interoperate with Swift, it is very useful to include nullable or nonnull property attributes. If you add it in any part of a header file, you will need to specify it for all parts of the header file (compiler warnings will help you). It's even quite useful for Objective-C callers to know from the method signature what may and may not be a nil value.
Another property of note is class. You can add a property to the class.
Adding these two items together, and if you are implementing a singleton,
+ (MyClass *)sharedInstance;
it's quite useful to define it as a property:
#property (class, nonatomic, nonnull, readonly) MyClass *sharedInstance;
(In which case you are required to add a backing variable for it as described in this article)
This will let you access the shared instance via dot notation.
[MyClass.sharedInstance showMeTheMoney:YES];
And in Swift, the rather annoying
MyClass.sharedInstance()?.showMeTheMoney(true)
turns into
MyClass.sharedInstance.showMeTheMoney(true)
‡ maybe it's just 3 characters to you, but it keeps my head from exploding mid-day.
Edit:
I would add, try out
+ (instancetype)shared;
This 1) shortens the naming to concur with modern Swift convention, and 2) removes the hardcoded type value of a (MyClass *).

Is there an actual reason why do we have to use #synthesize?

So I use the #property key in my header file.
If I do that, I should use the #synthesize key in my implementation, right? But I wonder, is there an actual reason I have to do that? I'm just wondering why isn't writing #property in the header just about enough for the to code know my intentions (having the get/set methods automagically generated).
Sure, according to Why we have to synthesize? we write #synthesize to generate the get/set methods. But my question is about why isn't #property in the header just enough for this?
I ask because whenever I write #property in my header, I immediately go to the implementation and write #synthesize. So for me, the only reason #synthesize is used is to complement the #property keyword. Which seems rather redundant, and makes me assume that #synthesize wouldn't exist if it wasn't because it has other uses. What are those other uses?
#synthesize does two things. It generates the getter/setter pair and it creates the iVar for the property.
Of these two things, I think the iVar creation is the key to when I use #synthesize and when I don't. When create properties for members that are not internally stored as iVars, then (obviously) I don't use #synthesize.
The upcoming auto synthesize feature is not going to be of much help. I always name my iVars with a leading '_', and so I will still need to explicitly synthesize them.
See #AndrewMadsen link: it looks like '_' prefix auto synthesize will generate the iVars.
W00t! Needless to say, I'm much more excited about auto synthesize now!!
As it generates the getters and setters for the instance variables, both to use internally and to use from outside your class, the real magic is found in the setter, as it does the following:
- (void)setValue: (id)newValue
{
if (value != newValue)
{
[value release];
value = newValue;
[value retain];
}
}
This is for a #property (nonatomic, retain)...
The real magic is, that each time you set your instance variable (from in- or outside the object itself) you want to make sure, that you own the passed newValue (with retain), release the old value and set the new value.
So it is possible to set the instance Variable multiple times, without having to manually release the old one. Thats only a speed option :-)

Why do I keep seeing double property declarations? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When do I need to have both iVar and a property?
I keep seeing the following in objective-C code.
#interface Contact : RKObject {
NSNumber* _identifier;
NSString* _name;
NSString* _company;
}
#property (nonatomic, retain) NSNumber* identifier;
#property (nonatomic, retain) NSString* name;
#property (nonatomic, retain) NSString* company;
Why is the bit inside of the block with the interface also required? Is that instead of using #synthesize?
The block inside the #interface are the ivars for your class, while the 3 elements below it are the properties, that is accessors (getters and setters) for your ivars.
You typically access an object’s properties (in the sense of its
attributes and relationships) through a pair of accessor
(getter/setter) methods. By using accessor methods, you adhere to the
principle of encapsulation. You can exercise tight
control of the behavior of the getter/setter pair and the underlying
state management while clients of the API remain insulated from the
implementation changes.
Although using accessor methods therefore has significant advantages,
writing accessor methods is a tedious process. Moreover, aspects of
the property that may be important to consumers of the API are left
obscured—such as whether the accessor methods are thread-safe or
whether new values are copied when set.
Declared properties address these issues by providing the following
features:
The property declaration provides a clear, explicit specification of how the accessor methods behave.
The compiler can synthesize accessor methods for you, according to the specification you provide in the declaration.
Properties are represented syntactically as identifiers and are scoped, so the compiler can detect use of undeclared properties.
Reference : https://developer.apple.com/library/mac/#documentation/cocoa/conceptual/objectiveC/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW1
Extending Dr. kameleon's answer, the iVars are unnecessary in this case, as they can be declared explicitly at the #synthesize line. For instance, #synthesize name = _name would be the same as declaring the iVar in the .h (note that the property is required for this syntax). Neither one is more OK than the other, one is just more efficient coding.

Obj-C, properties for everything

I have started work at a new company and one of the guidelines I have been told to adhere to by my team lead is to rarely use retain/release and instead rely on properties for memory management. I can see the appeal of keeping the code clear and leaving less room for mistakes but opening up the interfaces like this makes me uncomfortable. Generally speaking the architecture is very good but I have always been pedantic about closing up my classes to the outside world.
Is using properties like this an accepted design methodology in objective-c? Can anyone provide me with links or a clue where my new team may have picked up this strategy?
There is no need to expose properties to the entire world. In your implementation .m file you can add a little category to declare 'private' properties. E.g.
#import "Class.h"
#interface Class ()
#property (nonatomic, strong) NSDate *privateProperty
#end
#implementation Class
#synthesize privateProperty;
...
#end
Nothing in Objective-C is ever really private in strict terms, so I'd say this was good practice — it hides almost all of the retain/release stuff without requiring an ARC-compatible runtime and has the side effect of not requiring you to mention your instance variables in the header at all (though there are other ways to achieve that).
As a historical note, I think this was the first way to move instance variables out of the header — which is something permitted only by the 'new' runtime on iOS and 64bit Intel 10.6+ — so that may be a secondary reason why your team have settled upon it. Unless they've explicitly told you to make your classes transparent, they may actually be completely in agreement with your feeling (and the well accepted object oriented principle) that implementations should be opaque.
You don't have to declare your properties publicly. Using a class category or class extension, you can place your properties within the implementation.
For example:
// in AnObject.h
#interface AnObject : NSObject
#end
// in AnObject.m
#interface AnObject () // () is class extension, (foo) is a class category
#property (retain) NSString *foo;
#end
#implementation AnObject
#synthesize foo;
#end
For more information, see Apple's documentation.