Basic Objective C defining and synthesizing properties - objective-c

I have been working with Objective C for a few months now and feel like I maybe know 1% of it, and understand even less than that...
Regardless, I have two moderately popular games out, and learning more every day.
When I first started, I learned that the method of defining properties was to use the same identifier for the property and the instance variable, as follow:
code.h:
#interface MyClass : UISomething {
NSString *myPropName;
}
#property (nonatomic, retain) NSString *myPropName;
#end
code.m
#synthesize myPropName;
Recently I saw the following used, where the instance variable is named differently than the property, and then the property is set to the instance variable in the implementation:
code.h:
#interface MyClass : UISomething {
NSString *_myPropName;
}
#property (nonatomic, retain) NSString *myPropName;
#end
code.m:
#synthesize myPropName = _myPropName;
Is there a reason for not using same identifier for the property and instance variable?
Thanks!
Hanaan

Is there a reason for not using same
identifier for the property and
instance variable?
Not really. Some people like the convention of prefixing the instance variables with an underscore. (Seems pointless to me.) Other people like to change the property names for boolean variables:
#synthesize isEmpty = empty;
You might also want to use a shorter identifier for the instance variable and more descriptive name for the property (audioPlayer = player). And one final application comes to mind, renaming variables in combination with protocols:
#interface LowLevelAudioPlayer : NSObject <AudioLevelProvider> {…}
#interface Jukebox : NSObject {
LowLevelAudioPlayer *player;
}
#property(readonly) id <AudioLevelProvider> levelMeter;
#synthesize levelMeter = player;
Here it’s beneficial to rename the variable as you are only providing access to one of its facets.

Related

Modern Objective-C and #synthesize

I'm trying convert my code to Modern Objective-C style. How i read here http://www.techotopia.com/index.php/The_Basics_of_Modern_Objective-C": "In the case of Modern Objective-C, however, the synthesis takes place by default, making the use of #synthesize declarations unnecessary. When using default property synthesize, instance variable properties are accessible from within code using the property name prefixed with an underscore."
However, I have:
Relationship.h
#interface Relationship : NSObject <NSCoding>
//...
#property(nonatomic, weak) Person* first;
//...
#end`
OtherRelationship.h
#import "Relationship.h"
#interface OtherRelationship : Relationship
#end
OtherRelationship.m
#import "OtherRelationship.h"
#implementation OtherRelationship
#synthesize first = _first;
- (void)foo
{
NSLog(#"%#", _first);
}
and it's working. But when i delete
#synthesize first = _first;
i get "Use of undeclared identifier '_first'" error. Does inheritanced variables doesn't work with autosynthesize or should i looking for problem elsewhere?
The backing ivar in the superclass is #private to the subclass. That is, the subclass may call self.first, but not _first. If you want to #synthesize again, use a different name because you can't refer to _first. For example, replace with #synthesize first = _ffirst; or just drop the #synthesize.

Objective C: Should I assign the variable AND create a property or is just one of them enough?

I have got a header file (.h) and I want to declare name but all these ways work the same I think because I haven't seen any difference with functionality. Could you tell me what the difference is between:
This with both declarations:
#interface someClass : UIViewController
{
NSString *name;
}
#property (nonatomic, copy) NSString *name;
#end
Without variable:
#interface someClass : UIViewController
{
}
#property (nonatomic, copy) NSString *name;
#end
Or Without property:
#interface someClass : UIViewController
{
NSString *name;
}
#end
#interface someClass : UIViewController
{
NSString *name;
}
#property (nonatomic, copy) NSString *name;
#end
Doing this you will explicitly declare both a property and an ivar.
A property is just a set of methods:
- (void)setName:(NSString*)name;
- (NSString*)name;
An ivar is the memory store holding the value that the property methods manage. This allows you to do:
self.name = ... // access through setter method
name = ... // direct access
The advantage of using properties is that they deal with memory management for you. E.g., in your case, the property is of type copy: this means that with the first syntax (self.name = ...) a copy of the object will be done. If not using properties, you would explicitly need to do: name = [originalString copy]; to obtain the same effect.
Other options you can specify for properties (but not ivars) are: strong and weak ownerships.
Furthermore, a property also represents a public interface to access the variable from outside your class.
Using direct access you are on your own as to memory management (if you are not using ARC).
If you are using ARC and don't define properties, you will not be able to control how the memory is managed by specifying the ownership: strong, weak, retain).
#interface someClass : UIViewController
{
}
#property (nonatomic, copy) NSString *name;
#end
Here you only declare the properties; the ivar is "inferred" by the #synthesize directive in your implementation file. This is only possible in Objective C 2.0 and later (previously, the ivar declaration as above was mandatory).
The same considerations as above applies, with a minor nuance: with older versions of LLVM (ObjC compiler) you will not be able to reference directly the auto-synthesized ivar; with current version of LLVM, if you omit the #synthesize directive, then an automatic ivar named after your property would also be declared (in your case it would be _name).
This last paragraph may seem a bit "advanced", or contrived, but you can safely ignore it.
#interface someClass : UIViewController
{
NSString *name;
}
#end
In this case you are only declaring the ivar. No accessor methods. You will need to handle memory management on your own (if not using ARC), futhermore you will not be able to access the variable from outside the class. For that you need accessors.
Hope this helps.
Case 1:
The is the old method, here the #property and variable are not related until you #synthesize name = name;
Access methods :
variable : name = #"hello"; //direct access to viariable
setter/getter : self.name = #"hello" // set value to name using setName: selector
With the latest xcode just the property is enough.
Case 2:
the new xcode style. Here the synthesize and variable creation is taken care by the compiler. (so less 2 lines of code and this also helps with memory management)
Access methods :
variable : _name = #"hello"; //direct access to viariable
setter/getter : self.name = #"hello" // set value to name using setName: selector
Case 3:
Here the name is just a variable and it dose not have a setter or a getter.
with out property (or) setter & getter this is as good as a local variable and it cannot be accessed from other objects.

objective-c member var and property statement usage

Recently I have started learning Objective-C, and I get puzzled about the member var and property. I want to know what's the difference between the following three code blocks:
1.
#interface Application
{
UserInfo* userInfo;
ApplicationInfo*applicationInfo;
}
#property (retain) UserInfo*userInfo; // #synthesize userInfo;
#property (retain) ApplicationInfo* applicationInfo ; // #synthesize applicationInfo;
#end
2.
#interface Application
{
}
#property (retain) UserInfo*userInfo; // #synthesize userInfo;
#property (retain) ApplicationInfo* applicationInfo ; // #synthesize applicationInfo;
#end
3.
#interface Application
{
UserInfo* userInfo;
ApplicationInfo*applicationInfo;
}
#end
Thank you very much!
1: This declares instance variables with accompanying declared properties. When you synthesise the properties, for example the property foo, the foo and setFoo methods are automatically generated which refer to the instance variables (due to having the same name), and these are called when you use dot notation (e.g. someInstance.foo = bar) to access them. Because you defined the properties to be retain, when you assign an object to the property using the setter or through dot notation, the existing object pointed to by the instance variable is released and the new object is assigned to the instance variable and retained.
2: Exactly the same as 1. The instance variables are implied.
3: The instance variables are there, but the properties are not, so you won't be able to access them through dot notation and no getter/setter methods are synthesised.
I strongly recommend reading the official documentation on this, it's quite clear and lays it all out in a fairly straightforward manner.

Difference between methods of assigning property in Objective-C

Here are 2 methods to assign property in Objective-C :
METHOD 1
// in header
#interface Book : NSObject {
NSString *_title;
}
#property (nonatomic, retain) NSString *title;
// in implementation
#implementation Book
#synthesize title = _title;
METHOD 2
// in header
#interface Book : NSObject {
NSString *title;
}
#property (nonatomic, retain) NSString *title;
// in implementation
#implementation Book
#synthesize title;
What are the difference? I use Method 1 recently, as more tutorials recommend Method 1, but nobody explains why.
The difference is the names. In #2 the property and instance field have the same name. In #1 they have different names.
The advantage to #1 is that it's difficult to accidentally reference the property when you mean the instance field or vice-versa. Referencing the wrong one can lead to having a object retained twice or not retained at all.
The advantage to #2 is that it's marginally simpler, and it works fine if you're careful and a bit formal in your use of things.
[And, I see, one flavor specifies assign and the other retain, which is a whole different lecture. You'd not normally use assign with an object pointer.]
Firstly, I recommend you use copy instead of retain(and assign) for NSString type of instance. If it's Mutable, then it gets copied; If not, then it just gets retained.
Maybe you'll like THIS DISCUSSION.
And for you question, the difference is that first one use the same name and the second one use the different name for iVar & property.
Actually, you have a METHOD 3 to use:
// in header
#interface Book : NSObject {
}
#property (nonatomic, copy) NSString *title;
// in implementation
#implementation Book
#synthesize title;
For #synthesize to work in the legacy runtime, you must either provide an instance variable with the same name and compatible type of the property or specify another existing instance variable in the #synthesize statement. With the modern runtime, if you do not provide an instance variable, the compiler adds one for you. For example, given the following class declaration and implementation.
Here is a sample code of official doc, you can make it clear( it includes difference between your METHOD 1 & METHOD 2):
#interface MyClass : NSObject {
float sameName;
float otherName;
}
#property float sameName;
#property float differentName;
#property float noDeclaredIvar;
#end
#implementation MyClass
#synthesize sameName;
#synthesize differentName=otherName;
#synthesize noDeclaredIvar;
#end
The compiler for the legacy runtime would generate an error at #synthesize noDeclaredIvar; whereas the compiler for the modern runtime would add an instance variable to represent noDeclaredIvar.
Note: iPhone applications and 64-bit programs on Mac OS X v10.5 and later use the modern version of the runtime. Other programs (32-bit programs on Mac OS X desktop) use the legacy version of the runtime. You can refer it HERE).
However, I suggest to use METHOD 1 or METHOD 3. As you can just use self.title in code, the property will help you manage the alloc & release. If you use METHOD 2, you may mix title with self.title(but _title is more clear, uh?). :)

Do I need to declare a property in the instance variables section, too? What do I gain?

I read some tutorials here about properties ,but i still have some doubts to clarify, is there a difference between
#interface MyClass : NSObject {
}
#property(nonatomic,retain) NSString *temp;
#end
AND
#interface MyClass : NSObject {
NSString *temp;
}
#property(nonatomic,retain) NSString *temp;
#end
The difference is that in the first version, the compiler will automatically create an instance variable (IIRC, it will be named _temp but I don't know for sure). This is only supported on iOS and Mac 64 bit.
In the second example, you provide the variable.
There's actually a way to tell the compiler which variable to use for the property, which I use a lot:
#interface MyClass : NSObject {
NSString *temp_;
}
#property(nonatomic,retain) NSString *temp;
#end
#implementation MyClass
#synthesize temp = temp_;
#end
This way the variable and the property have different names and you can't confuse them (e.g. by forgetting to prefix self.).
Minor side-note: it's often desirable to use copy instead of retain for NSString *, since you might assign an NSMutableString * to the property. Now if you would change that mutable string unexpected things might happen.
Does the first one even work? If there is no instance variable its a bit hard to have a property to access it.
#properties are meant for you, so you can be lazy, they write the following 2 methods for you ( if not set to readonly ):
- (void)setYourVariable:(id)new;
- (id)yourVariable;
it also allows you to use "someClass.itsVariable;" instead of "[someClass itsVariable];"
Another thing, when you create your header files make sure that the biggest variables ( like pointers ) are on the top and the smallest on the bottom, this saves ram.
thus:
NSObject *someObject;
NSObject *someOtherObject;
int anInt;
short aShort;
BOOL fakeBool;
instead of:
BOOL fakeBool;
NSObject *someObject;
short aShort;
NSObject *someOtherObject;
int anInt;
This has to do with the compiler, you can check this by using sizeof()
In the modern runtime (Objective-C 2.0) it is the same because the compiler will generate the variable for you. See Question about #synthesize
Quoting The Objective-C Programming Language > Declared Properties > Property Implementation Directives:
There are differences in the behavior of accessor synthesis that
depend on the runtime:
For the legacy runtimes, instance variables must already be declared in the #interface block of the current class. If an instance
variable of the same name as the property exists, and if its type is
compatible with the property’s type, it is used—otherwise, you get a
compiler error.
For the modern runtimes, instance variables are synthesized as needed. If an instance variable of the same name already exists, it is
used.
The practical difference that I've found is that the debugger doesn't appear to show you the value of properties, just instance variables.
Therefore, your first example, which (assuming you use the #synthesize directive to create your getter/setter) automatically creates the ivar, will not have a value that you can easily retrieve during debug. You'll end up having to send a lot of NSLog messages, rather than just looking at the values while stepping through your code.
As an aside, which seems to relate to this topic, I typically prepend my ivars with "iv" and change my color settings in XCode preferences so that I'm never unsure whether I'm accessing a property or an ivar.
Example
#interface MyClass : NSObject {
NSString *ivName;
NSString *ivTitle;
}
#property (nonatomic, copy) NSString *Name;
#property (nonatomic, copy) NSString *Title;
#end
Now, this then requires a small trick (to tie the two together) when synthesizing the properties, which I show below:
#implementation MyClass
#synthesize Name = ivName;
#synthesize Title = ivTitle;
This way, it's always very easy for me to know exactly what's going on at a glance. Yes, context can also tell you whether you're accessing an ivar/property, but why not make it easier?