What exactly does #synthesize do? - iphone

I have seen the following piece of code:
//example.h
MKMapView * mapView1;
#property (nonatomic, retain) MKMapView * mapView;
//example.m
#synthesize mapView = mapView1
What is the relation between mapView and mapView1?
Does it create a set and get method for mapView1?

In your example, mapView1 is an instance variable (ivar), a piece of memory storage that belongs to an instance of the class defined in example.h and example.m. mapView is the name of a property. Properties are attributes of an object that can be read or set using the dot notation: myObject.mapView. A property doesn't have to be based on an ivar, but most properties are. The #propertydeclaration simply tells the world that there is a property called mapView.
#synthesize mapView = mapView1;
This line tells the compiler to create a setter and getter for mapView, and that they should use the ivar called mapView1. Without the = mapView1 part, the compiler would assume that the property and ivar have the same name. (In this case, that would produce a compiler error, since there is no ivar called mapView.)
The result of this #synthesize statement is similar to if you had added this code yourself:
-(MKMapView *)mapView
{
return mapView1;
}
-(void)setMapView:(MKMapView *)newMapView
{
if (newMapView != mapView1)
{
[mapView1 release];
mapView1 = [newMapView retain];
}
}
If you do add that code to the class yourself, you can replace the #synthesize statement with
#dynamic mapView;
The main thing is to have a very clear conceptual distinction between ivars and properties. They are really two very different concepts.

#synthesize creates a getter and a setter for the variable.
This lets you specify some attributes for your variables and when you #synthesize that property to the variable you generate the getter and setter for the variable.
The property name can be the same as the variable name. Sometimes people want it to be different so as to use it in init or dealloc or when the parameter is passed with the same variable's name.

From the documentation:
You use the #synthesize keyword to tell the compiler that it should synthesize the setter and/or getter methods for the property if you do not supply them within the #implementation block.

As I just run into this problem when editing legacy code I want to make additional notes to the existing answers one needs to be aware of.
Even with a newer compiler version it sometimes does make a difference if you omit #synthesize propertyName or not.
In the case you declare an instance variable without underscore while still synthesizing it, such as:
Header:
#interface SomeClass : NSObject {
int someInt;
}
#property int someInt;
#end
Implementation:
#implementation SomeClass
#synthesize someInt;
#end
self.someInt will access the same variable as someInt. Not using a leading underscore for ivars does not follow the naming conventions but I just came into a situation where I had to read and modify such code.
But if you now think "Hey, #synthesize is not important any more as we use a newer compiler" you are wrong! Your class then will result in having two ivars, namely someInt plus an autogenerated _someInt variable. Thus self.someInt and someInt will not address the same variables any more. If you don't expect such behavior as I did this might get you some headache to find out.

As per apple documentation #Synthesize is used only to rename instance variables. For example
#property NSString *str;
#synthesize str = str2;
Now in the class you can not use _str as the above line has renames the instance variable to str2
#property allows objects to be used by objects in other classes, or in other words makes the object public.

When you create a property in #interface, that property will be automatically back by an instance variable named as _propertyName.
So when you create a property named as firstName, behind the scene compiler will create an instance variable named as _firstName by default. Compiler will also create the getter and setter method for you(i.e. firstName, setFirstName).
Now when you synthesize the property by #synthesize firstName, you are simply telling the compiler rename my instance variable(_firstName) by firstName. If you want to rename your backed up instance variable by different name you can simply assign different name while synthesizing the property name(i.e. #synthesize firstName = myFirstName), by doing this your property is backed up by an instance variable named as myFirstname.
So, in short, most of the time #synthesize used to rename your instance variable backed up by your property.

See the apple docs
Basically the synthesize creates a setMapView and mapView methods which set and get mapView1

It creates getter and setter for your object. You can access with something like this :
MKMapView* m = object.mapView;
or
object.mapView = someMapViewObject
mapView1 is the name of the ivar in the class, mapView is the name for the getter / setter method(s).

Related

How to use a variable from another class in objective c

basically the problem I have is this:
helloworldlayer in class I have a variable that I want to show in another class.
in classe helloworldlayer.h
#interface HelloWorldLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate>
{
int _probar;
}
#property (nonatomic,readwrite)int probar;
and the helloworldlayer.m
#synthesize probar=_probar;
for use in other classe I do this
HelloWorldLayer *myobject = [[HelloWorldLayer alloc] init];
distan = myobject.probar;
everything works perfect if the Variable _probar give a value
in the init helloworldlayer.m example:
_probar = 20;
but if I put a variable constant while changing does not work. for example
- (void)updateDistancia:(ccTime)dt
{
otra =+1;
_probar = otra;
}
in the other class tells me that equals zero, and i do not understand why, if someone tells me that this will be happening much appreciate or you have another solution.
I think removing int _probar; will solve the issue.
#property (nonatomic,readwrite)int probar; will automatically be backed by a iVar named _probar and have getter and setter generated. So the #synthesize probar=_probar; is not needed.
#synthesize probar=someName; is only telling the compiler to back the property with a iVar named someName instead of the default name. In your case you already have an iVar with the default name so the property and iVar is pointing at different ints.

Declaration/definition of variables locations in ObjectiveC?

Ever since starting to work on iOS apps and objective C I've been really puzzled by the different locations where one could be declaring and defining variables. On one hand we have the traditional C approach, on the other we have the new ObjectiveC directives that add OO on top of that. Could you folks helps me understand the best practice and situations where I'd want to use these locations for my variables and perhaps correct my present understanding?
Here's a sample class (.h and .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
#end
and
#import "SampleClass.h"
// 4) what goes here?
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
#implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
#end
My understanding of 1 and 4 is that those are C-style file-based declarations and definitions that have no understanding whatsoever of the concept of class, and thus have to be used exactly how they would be used in C. I've seen them used for implementing static variable-based singletons before. Are there other convenient uses I'm missing?
My take from working with iOS is that ivars have been alost completely phased out outside of the #synthesize directive and thus can be mostly ignored. Is that the case?
Regarding 5: why would I ever want to declare methods in private interfaces? My private class methods seem to compile just fine without a declaration in the interface. Is it mostly for readability?
Thanks a bunch, folks!
I can understand your confusion. Especially since recent updates to Xcode and the new LLVM compiler changed the way ivars and properties can be declared.
Before "modern" Objective-C (in "old" Obj-C 2.0) you didn't have a lot of choices. Instance variables used to be declared in the header between the curly brackets { }:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#end
You were able to access these variables only in your implementation, but not from other classes. To do that, you had to declare accessor methods, that look something like this:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
- (int)myVar;
- (void)setMyVar:(int)newVar;
#end
// MyClass.m
#implementation MyClass
- (int)myVar {
return myVar;
}
- (void)setMyVar:(int)newVar {
if (newVar != myVar) {
myVar = newVar;
}
}
#end
This way you were able to get and set this instance variable from other classes too, using the usual square bracket syntax to send messages (call methods):
// OtherClass.m
int v = [myClass myVar]; // assuming myClass is an object of type MyClass.
[myClass setMyVar:v+1];
Because manually declaring and implementing every accessor method was quite annoying, #property and #synthesize were introduced to automatically generate the accessor methods:
// MyClass.h
#interface MyClass : NSObject {
int myVar;
}
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#synthesize myVar;
#end
The result is much clearer and shorter code. The accessor methods will be implemented for you and you can still use the bracket syntax as before. But in addition, you can also use the dot syntax to access properties:
// OtherClass.m
int v = myClass.myVar; // assuming myClass is an object of type MyClass.
myClass.myVar = v+1;
Since Xcode 4.4 you don't have to declare an instance variable yourself anymore and you can skip #synthesize too. If you don't declare an ivar, the compiler will add it for you and it will also generate the accessor methods without you having to use #synthesize.
The default name for the automatically generated ivar is the name or your property starting with an underscore. You can change the generated ivar's name by using #synthesize myVar = iVarName;
// MyClass.h
#interface MyClass : NSObject
#property (nonatomic) int myVar;
#end
// MyClass.m
#implementation MyClass
#end
This will work exactly as the code above. For compatibility reasons you can still declare ivars in the header. But because the only reason why you would want to do that (and not declare a property) is to create a private variable, you can now do that in the implementation file as well and this is the preferred way.
An #interface block in the implementation file is actually an Extension and can be used to forward declare methods (not needed anymore) and to (re)declare properties. You could for instance declare a readonly property in your header.
#property (nonatomic, readonly) myReadOnlyVar;
and redeclare it in your implementation file as readwrite to be able to set it using the property syntax and not only via direct access to the ivar.
As for declaring variables completely outside of any #interface or #implementation block, yes those are plain C variables and work exactly the same.
First, read #DrummerB's answer. It a good overview of the whys and what you should generally do. With that in mind, to your specific questions:
#import <Foundation/Foundation.h>
// 1) What do I declare here?
No actual variable definitions go here (it's technically legal to do so if you know exactly what you're doing, but never do this). You may define several other kinds of things:
typdefs
enums
externs
Externs look like variable declarations, but they're just a promise to actually declare it somewhere else. In ObjC, they should only be used to declare constants, and generally only string constants. For instance:
extern NSString * const MYSomethingHappenedNotification;
You would then in your .m file declare the actual constant:
NSString * const MYSomethingHappenedNotification = #"MYSomethingHappenedNotification";
#interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
As noted by DrummerB, this is legacy. Don't put anything here.
// 3) class-specific method / property declarations
#end
Yep.
#import "SampleClass.h"
// 4) what goes here?
External constants, as described above. Also file static variables can go here. These are the equivalent of class variables in other languages.
#interface SampleClass()
// 5) private interface, can define private methods and properties here
#end
Yep
#implementation SampleClass
{
// 6) define ivars
}
But very rarely. Almost always you should allow clang (Xcode) to create the variables for you. The exceptions are usually around non-ObjC ivars (like Core Foundation objects, and especially C++ objects if this is an ObjC++ class), or ivars that have weird storage semantics (like ivars that don't match with a property for some reason).
// 7) define methods and synthesize properties from both public and private
// interfaces
Generally you shouldn't #synthesize anymore. Clang (Xcode) will do it for you, and you should let it.
Over the last few years, things have gotten dramatically simpler. The side-effect is that there are now three different eras (Fragile ABI, Non-fragile ABI, Non-fragile ABI + auto-syntheisze). So when you see the older code, it can be a little confusing. Thus confusion arising from simplicity :D
I'm also pretty new, so hopefully I don't screw anything up.
1 & 4: C-style global variables: they have file wide scope. The difference between the two is that, since they're file wide, the first will be available to anyone importing the header while the second is not.
2: instance variables. Most instance variables are synthesized and retrieved/set through accessors using properties because it makes memory management nice and simple, as well as gives you easy-to-understand dot notation.
6: Implementation ivars are somewhat new. It's a good place to put private ivars, since you want to only expose what's needed in the public header, but subclasses don't inherit them AFAIK.
3 & 7: Public method and property declarations, then implementations.
5: Private interface. I always use private interfaces whenever I can to keep things clean and create a kind of black box effect. If they don't need to know about it, put it there. I also do it for readability, don't know if there are any other reasons.
This is an example of all kinds of variables declared in Objective-C. The variable name indicate its access.
File: Animal.h
#interface Animal : NSObject
{
NSObject *iProtected;
#package
NSObject *iPackage;
#private
NSObject *iPrivate;
#protected
NSObject *iProtected2; // default access. Only visible to subclasses.
#public
NSObject *iPublic;
}
#property (nonatomic,strong) NSObject *iPublic2;
#end
File: Animal.m
#import "Animal.h"
// Same behaviour for categories (x) than for class extensions ().
#interface Animal(){
#public
NSString *iNotVisible;
}
#property (nonatomic,strong) NSObject *iNotVisible2;
#end
#implementation Animal {
#public
NSString *iNotVisible3;
}
-(id) init {
self = [super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
iPrivate = #"iPrivate";
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
_iPublic2 = #"iPublic2";
iNotVisible = #"iNotVisible";
_iNotVisible2 = #"iNotVisible2";
iNotVisible3 = #"iNotVisible3";
}
return self;
}
#end
Note that the iNotVisible variables are not visible from any other class. This is a visibility issue, so declaring them with #property or #public doesn't change it.
Inside a constructor it's good practice to access variables declared with #property using underscore instead self to avoid side effects.
Let's try to access the variables.
File: Cow.h
#import "Animal.h"
#interface Cow : Animal
#end
File: Cow.m
#import "Cow.h"
#include <objc/runtime.h>
#implementation Cow
-(id)init {
self=[super init];
if (self){
iProtected = #"iProtected";
iPackage = #"iPackage";
//iPrivate = #"iPrivate"; // compiler error: variable is private
iProtected2 = #"iProtected2";
iPublic = #"iPublic";
self.iPublic2 = #"iPublic2"; // using self because the backing ivar is private
//iNotVisible = #"iNotVisible"; // compiler error: undeclared identifier
//_iNotVisible2 = #"iNotVisible2"; // compiler error: undeclared identifier
//iNotVisible3 = #"iNotVisible3"; // compiler error: undeclared identifier
}
return self;
}
#end
We can still access the not visible variables using the runtime.
File: Cow.m (part 2)
#implementation Cow(blindAcess)
- (void) setIvar:(NSString*)name value:(id)value {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
object_setIvar(self, ivar, value);
}
- (id) getIvar:(NSString*)name {
Ivar ivar = class_getInstanceVariable([self class], [name UTF8String]);
id thing = object_getIvar(self, ivar);
return thing;
}
-(void) blindAccess {
[self setIvar:#"iNotVisible" value:#"iMadeVisible"];
[self setIvar:#"_iNotVisible2" value:#"iMadeVisible2"];
[self setIvar:#"iNotVisible3" value:#"iMadeVisible3"];
NSLog(#"\n%# \n%# \n%#",
[self getIvar:#"iNotVisible"],
[self getIvar:#"_iNotVisible2"],
[self getIvar:#"iNotVisible3"]);
}
#end
Let's try to access the not visible variables.
File: main.m
#import "Cow.h"
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
#autoreleasepool {
Cow *cow = [Cow new];
[cow performSelector:#selector(blindAccess)];
}
}
This prints
iMadeVisible
iMadeVisible2
iMadeVisible3
Note that I was able to access the backing ivar _iNotVisible2 which is private to the subclass. In Objective-C all variables can be read or set, even those that are marked #private, no exceptions.
I didn't include associated objects or C variables as they are different birds. As for C variables, any variable defined outside #interface X{} or #implementation X{} is a C variable with file scope and static storage.
I didn't discuss memory management attributes, or readonly/readwrite, getter/setter attributes.

Objective C: Which is changed, property or ivar?

Worrying about duplicates but can not seem to find and answer I can understand in any of the other posts, I just have to ask:
When I have in my .h:
#interface SecondViewController : UIViewController{
NSString *changeName;
}
#property (readwrite, retain) NSString *changeName;
then in my .m
#synthesize changeName;
-(IBAction)changeButton:(id)sender{
changeName = #"changed";
}
Is it the synthesized property or the instance variable that get changed when I press "changeButton" ?
You (and it seems some of the others that answered) are confusing properties with actual variables.
The way properties work is, they create METHODS (called setter and getter) that set or get/return ivars. And the do notation (self.string) actually INVOKES these methods. So a property can't be CHANGED, only the declared iVar is.
When you declare a property like so:
#property (nonatomic, retain) NSString *string;
And #synthesize it the following happens:
An iVar called string (of type NString*) is created
(if you do
#synthesize string = whateverYouWant
the iVar created
is called whateverYouWant - a convention is to name the iVars
the same as the property with preceding underscore (_string))
an accessor method is created like this
-(NSString*) string;
a setter is created like this
-(void) setString: (NSString*) newString;
Now what self.xxxx does is, it actually sends the message xxxx to self
(like [self xxxx]).
It works with ANY method, not just properties, though it should only
Be used with properties.
So when you do self.string = #"hello" it actually comes down to
[self setString: #"hello"];
(Note that the compiler actually knows you are trying to set and so the
setString message is sent instead of just string. If you accessed self.string
it would send [self string])
Thus you don't SET a property, you invoke the (synthesized) setter method that in
itself sets the iVar.
Accessing your iVar directly is ok, if you know what your doing.
Just calling
string = #"something else";
Will produce leaking code, since no memory management is done.
The synthesized accessors and setters actually do this for you, depending
on how you defined th property (retain,copy,assign).
Because the setter (for a retained property) doesn't just do
IVar = newValue
If you declared a retained property it actually looks something like this:
-(void) setString: (NSString*) newString {
if (string) [string release];
string = [newString retain];
}
So the property synthesize takes a bit of work off your hands.
EDIT
Since it still doesn't seem clear, the property that is declared is not to be thought
of like a variable. In the above example, when using
#synthesize string = _string;
there IS NO variable called "string". It's just the way you access the method structures
that set the iVar _string through the setter methods. Since string is no variable/object pointer, you cannot send messages to it ([string doSomething] won't work).
When you just synthesize the property using #synthesize string; the generated iVar gets
the same name as the property.
Calling [string doSomething] will then work, but it has nothing to do with the property. The "string" refers to the iVar. Hence th convention to name the iVars underscored, so
you don't accidentally access the iVar when you meant to use the getter/setter.
Both. Property uses instance variable as its storage. In your code you change the instance variable, but if you access the property (via self.changeName) you'd get the same value as instance variable.
Usually to distinguish between ivars and properties people use _ prefix for ivars. And then synthesizes properties like this:
#synthesize myProperty=_myProperty;
well, the var
it's always the var
in your case the property methods aren't used at all.
now, consider this case:
self.changeName = #"changed";
this way you are using the property, but that just means that you are using the methods "magically" created for you by the compiler, the setter and getter methods, where you, again, change the var (property doesn't exist, in reality, it's just a way to create the setter and getter methods for you)

When should I use the “self” keyword?

When should I be using the self expression in my iphone development applications? say i have 2 fields: UITextField *text1; and NSString *str1; retained and synthesized.
when i am accessing either of these 2 fields, when should i and when should i not use self.text1 and self.str1 ?
self is not a keyword, it is an expression. Additionally, you use it any time you want to refer to a method or property on yourself, or yourself directly. By "yourself" I am of course, referring to the instance of the class you are operating in.
There are certain circumstances where it's generally discouraged to use the self.-expression to access a property. Normally you always use self for any access of a property. It's the most secure and uncomplicated way. Especially if you used retain, then memory management will be done for you.
The two exceptions from this rule:
Any init method.
In dealloc.
In both cases you are dealing with an partially initialized object. There are some side effects that may occur when using setters or getters here -- because they are methods and hence may be overridden.
For example, take a class A with a property foo that has been subclassed by class B. The subclass B adds an property bar and overrode the setter for foo. Now your init-method calls setFoo:, because you used self.foo = ... with some initial value. The subclass, however, also accesses the value of bar in this setter. But in this case, it may happen that bar has never been initialized and points at some arbitrary data. Calling a setter in init my cause crashes, although the probability may not be too high in your own code.
In your example you aren't directly accessing instance variables when you use self, instead you're accessing the properties you've defined.
Consider this example:
#interface Foo : NSObject {
NSString *_bar;
}
#property (nonatomic, retain) NSString *bar;
#end
#implementation Foo
#synthesize bar = _bar;
-(void)baz {
_bar = #"ivar"; //accessing the ivar
self.bar = #"property"; //accessing the ivar via the property
}
#end
In general if you're using properties, there's little reason to utilize the ivar. This has the added benefit of automatically retaining & releasing values for you.
But other cases exist when your properties will have a readonly modifier. In these cases it's necessary to directly access your ivars in order to set their values.
It's also a good idea to use self within a method call sometimes if you have a custom getter. The managedContext object within a Core Data-using application is a good example. If you refer to it by self.managedContext, you can override and set the object to what it needs to be if it's nil. Refer to the code generated by XCode when creating an application that uses Core Data.
Here is an example of the code generated by XCode, actually:
#interface YourAppDelegate : NSObject <UIApplicationDelegate>
{
#private
NSManagedObjectContext *managedObjectContext_;
}
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#implementation ContractionTimerAppDelegate
/**
Returns the managed object context for the application.
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
*/
- (NSManagedObjectContext *)managedObjectContext {
if (managedObjectContext_ != nil) {
return managedObjectContext_;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
managedObjectContext_ = [[NSManagedObjectContext alloc] init];
[managedObjectContext_ setPersistentStoreCoordinator:coordinator];
}
return managedObjectContext_;
}
#end
if you "synthesize" the variable, you should "self." the variable. little rule of thumb
I don't know anything about objective-c, but this looks a lot like this keyword from other languages (like C++, C#, Java, PHP, and others). If so, then my advice is to use it always. That way, if you ever (accidentally) define a local variable with the same name, your code won't break.
However, I must also add, that this is somewhat of a religious debate with a history of flamewars in programmer communities. So take this advice with a grain of salt and use whatever seems to make most sense to you. Just be consistent about it.

Property vs. instance variable

I'm trying to understand how strategies some folks use to distinguish instance vars vs. properties. A common pattern is the following:
#interface MyClass : NSObject {
NSString *_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#end
#implementation MyClass
#synthesize myVar = _myVar;
Now, I thought the entire premise behind this strategy is so that one can easily distinguish the difference between an ivar and property. So, if I want to use the memory management inherited by a synthesized property, I'd use something such as:
myVar = #"Foo";
The other way would be referencing it via self.[ivar/property here].
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Thanks.
Properties are just setters and getters for ivars and should (almost) always be used instead of direct access.
#interface APerson : NSObject {
// NSString *_name; // necessary for legacy runtime
}
#property(readwrite) NSString *name;
#end
#implementation APerson
#synthesize name; // use name = _name for legacy runtime
#end
#synthesize creates in this case those two methods (not 100% accurate):
- (NSString *)name {
return [[_name copy] autorelease];
}
- (void)setName:(NSString *)value {
[value retain];
[_name release];
_name = value;
}
It's easy now to distinguish between ivars and getters/setters. The accessors have got the self. prefix. You shouldn't access the variables directly anyway.
Your sample code doesn't work as it should be:
_myVar = some_other_object; // _myVar is the ivar, not myVar.
self.myVar = some_other_object; // works too, uses the accessors
A synthesized property named prop is actually represented by two methods prop (returning the current value of the property) and setProp: (setting a new value for prop).
The self.prop syntax is syntactic sugar for calling one of these accessors. In your example, you can do any one of the following to set the property myVar:
self.myVar = #"foo"; // handles retain/release as specified by your property declaration
[self setMyVar: #"foo"]; // handle retain/release
_myVar = #"Foo"; // does not release old object and does not retain the new object
To access properties, use self.propname. To access instance variables use just the instance variable's name.
The problem with using the #synthesize myVar = _myVar strategy, is I figured that writing code such as:
myVar = some_other_object; // doesn't work.
The compiler complains that myVar is undeclared. Why is that the case?
Because the variable myVar is undeclared.
That statement uses the syntax to access a variable, be it an instance variable or some other kind. As rincewind told you, to access a property, you must use either the property-access syntax (self.myVar = someOtherObject) or an explicit message to the accessor method ([self setMyVar:someOtherObject]).
Otherwise, you're attempting to access a variable, and since you don't have a variable named myVar, you're attempting to access a variable that doesn't exist.
In general, I name my properties the same as my instance variables; this is the default assumption that the #property syntax makes. If you find you're fighting the defaults, you're doing it wrong (or your framework sux, which is not the case for Cocoa/Cocoa-touch in my opinion).
The compiler error you're getting is because property use always has to have an object reference, even inside your own class implementation:
self.stuff = #"foo"; // property setter
[stuff release]; // instance variable
stuff = #"bar"; // instance variable
return self.stuff; // property getter
I know that many Cocoa programmers disagree, but I think it's bad practice to use properties inside your class implementation. I'd rather see something like this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
[stuff release];
stuff = [theStuff copy];
// do something else
}
than this:
-(void) someActionWithStuff: (NSString*) theStuff {
// do something
self.stuff = theStuff;
// do something else
}
I prefer to do memory management as explicitly as possible. But even if you disagree, using the self.stuff form will clue in any experienced Objective-C programmer that you're calling a property rather than accessing an instance variable. It's a subtle point that's easy for beginners to gloss over, but after you've worked with Objective-C 2.0 for a while, it's pretty clear.
Don,
According to the "rules", you should call Release for every Copy, Alloc, and Retain. So why are you calling Release on stuff? Is this assuming it was created using Alloc, Copy, or Retain?
This brings up another question: Is it harmful to call Release on a reference to an object if it's already been released?
Since Apple reserves the _ prefix for itself, and since I prefer to make it more obvious when I am using the setter and when I am using the ivar, I have adopted the practive of using a prefix of i_ on my ivars, so for example:
#interface MyClass : NSObject {
NSString *i_myVar;
}
#property (nonatomic, retain) NSString *myVar;
#synthesize myVar = i_myVar;
i_myVar = [input retain];
self.myVar = anotherInput;
[i_myVar release]
Since it is quite important to know when you are using the setter and when you are using the ivar, I find the explicitly different name is safer.
In your question, it should be:
self.myVar = #"Foo"; // with setter, equivalent to [self setMyVar:#"Foo"]
and
_myVar = some_other_object; // direct ivar access - no memory management!
Remember that you should not use setters/getters in init/dealloc, so you need to do your direct ivar access (and careful memory management) iin those methods.
what's wrong with simply using
#interface MyClass : NSObject
#property NSString *prop;
#end
nonatomic and retain are not required, retain is the default, and atomic/nonatomic isn\t important unless XCode tells you with a warning.
it is NOT necessary to declare the iVar, one will be created for you named _prop, if you really want to use one (i don't see why to be honest)
#synthesize is NOT required.
when (and you should) using ARC you don't have to bother with retain and release either.
keep it simple !
furthermore, if you have a method like this one
- (void)aMethod:(NSString*)string
{
self.prop = string;
// shows very clearly that we are setting the property of our object
_aName = string;
// what is _aName ? the _ is a convention, not a real visual help
}
i would always use properties, more flexible, easier to read.