Is there a difference between an "instance variable" and a "property" in Objective-c?
I'm not very sure about this. I think that an "property" is an instance variable that has accessor methods, but I might think wrong.
An instance variable is a variable that exists and holds its value for the life of the object. The memory used for instance variables is allocated when the object is first created (through alloc ), and freed when the object is deallocated.
Each instance variable lives in memory for the life of the object it is owned by. Variables are properties an object knows about itself. All instances of an object have their own copies of instance variables, even if the value is the same from one object to another.
Instance properties are those properties that are defined inside any class and require an instance that is created with the help of the class name itself. Without creating the instance of the class, we may not be able to access these properties which are defined inside the class.
Accessing an ivar through a getter/setting involves an Objective-C method call, which is much slower (at least 3-4 times) than a "normal" C function call and even a normal C function call would already be multiple times slower than accessing a struct member.
A property is a more abstract concept. An instance variable is literally just a storage slot, like a slot in a struct. Normally other objects are never supposed to access them directly. A property, on the other hand, is an attribute of your object that can be accessed (it sounds vague and it's supposed to). Usually a property will return or set an instance variable, but it could use data from several or none at all. For example:
@interface Person : NSObject { NSString *name; } @property(copy) NSString *name; @property(copy) NSString *firstName; @property(copy) NSString *lastName; @end @implementation Person @synthesize name; - (NSString *)firstName { [[name componentsSeparatedByString:@" "] objectAtIndex:0]; } - (NSString *)lastName { [[name componentsSeparatedByString:@" "] lastObject]; } - (NSString *)setFirstName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@" "]; NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]]; self.name = [newNameArray componentsJoinedByString:@" "]; } - (NSString *)setLastName:(NSString *)newName { NSArray *nameArray = [name componentsSeparatedByString:@" "]; NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]]; self.name = [newNameArray componentsJoinedByString:@" "]; } @end
(Note: The above code is buggy in that it assumes the name already exists and has at least two components (e.g. "Bill Gates" rather than just "Gates"). I felt that fixing those assumptions would make the actual point of the code less clear, so I'm just pointing it out here so nobody innocently repeats those mistakes.)
A property is a friendly way of implementing a getter/setter for some value, with additional useful features and syntax. A property can be backed by an instance variable, but you can also define the getter/setter to do something a bit more dynamic, e.g. you might define a lowerCase property on a string which dynamically creates the result rather than returning the value of some member variable.
Here's an example:
// === In your .h === @interface MyObject { NSString *propertyName; } // ... @property (nonatomic, retain) NSString *propertyName; // === In your .m @implementation === @synthesize propertyName /* = otherVarName */;
The @property
line defines a property called propertyName
of type NSString *
. This can be get/set using the following syntax:
myObject.propertyName = @"Hello World!"; NSLog("Value: %@", myObject.propertyName);
When you assign to or read from myObject.propertyName
you are really calling setter/getter methods on the object.
The @synthesize
line tells the compiler to generate these getter/setters for you, using the member variable with the same name of the property to store the value (or otherVarName
if you use the syntax in comments).
Along with @synthesize
you can still override one of the getter/setters by defining your own. The naming convention for these methods is setPropertyName:
for the setter and propertyName
(or getPropertyName
, not standard) for the getter. The other will still be generated for you.
In your @property
line you can define a number of attributes in parens for the property that can automate things like thread-safety and memory management. By default a property is atomic meaning the compiler will wrap @synthesiz
ed get/set calls with appropriate locks to prevent concurrency issues. You can specify the nonatomic
attribute to disable this (for example on the iPhone you want to default most properties to nonatomic
).
There are 3 attribute values that control memory management for any @synthesized
setters. The first is retain
which will automatically send release
to old values of the property, and retain
to the new values. This is very useful.
The second is copy
which will make a copy of any values passed in rather than retaining them. It is good practice to use copy
for NSString because a caller could pass in an NSMutableString and change it out from under you. copy
will make a new copy of the input which only you have access to.
The third is assign
which does a straight pointer assign without calling retain/release on the old or new object.
Lastly you can also use the readonly
attribute to disable the setter for the property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With