Using instance variables with Modern Runtime - objective-c

I have several years of experience in Obj-c and Cocoa, but am just now getting back into it and the advances of Obj-C 2.0 etc.
I'm trying to get my head around the modern runtime and declaring properties, etc. One thing that confuses me a bit is the ability in the modern runtime to have the iVars created implicitly. And of course this implies that in your code you should always be using self.property to access the value.
However, in init* and dealloc(assuming you're not using GC) methods we should be using the iVar directly (in the current runtime).
So questions are:
Should we use property accessors in init* and dealloc with Modern Runtime?
If so, why is this different? Is it just because the compiler can't see the iVar?
If I need to override an accessor, can I still access that iVar that will be defined at runtime or do I have to define an actual iVar that the runtime will then use?
Again, if I can access the synthesized iVar, why can't I continue to do this for the init* and dealloc methods?
I read the docs several times, but they seemed a bit vague about all of this and I want to be sure that I understand it well in order to decide how I want to continue coding.
Hope that my questions are clear.
Quick summary of testing:
If you don't declare the ivar in legacy, compiler is completely unhappy
If you use #ifndef __OBJC2__ around ivar in legacy compiler is happy and you can use both ivar directly and as property
In modern runtime, you can leave the ivar undefined and access as property
In modern runtime, trying to access ivar directly without declaration gives error during compile
#private declaration of ivar, of course, allows direct access to ivar, in both legacy and modern
Doesn't really give a clean way to go forward right now does it?

In the current (OS X 10.5/GCC 4.0.1) compiler, you cannot directly access the runtime-synthesized ivars. Greg Parker, one of the OS X runtime engineers put it this way on the cocoa-dev list (March 12, 2009):
You can't in the current compiler. A
future compiler should fix that. Use
explicit #private ivars in the
meantime. An #private ivar should not
be considered part of the contract -
that's what #private means, enforced
by compiler warnings and linker
errors.
And why isn't there a way to
explicitly declare instance variables
in the .m file for the new runtime?
Three reasons: (1) there are some
non-trivial design details to work
out, (2) compiler-engineer-hours are
limited, and (3) #private ivars are
generally good enough.
So, for now you must use dot-notation to access properties, even in init and dealloc. This goes against the best practice of using ivars directly in these cases, but there's no way around it. I find that the ease of using runtime-synthesized ivars (and the performance benefits) outweigh this in most cases. Where you do need to access the ivar directly, you can use a #private ivar as Greg Parker suggests (there's nothing that prevents you from mixing explicitly declared and runtime-synthesized ivars).
Update With OS X 10.6, the 64-bit runtime does allow direct access to the synthesized ivars via self->ivar.

Since instance variables themselves can only be synthesized in the modern runtime (and must be declared in the #interface under 32-bit or pre-Leopard), it's safest / most portable to also declare the ivar
Should we use property accessors in init* and dealloc with Modern Runtime?
My rule of thumb is "possibly" for -init*, and "usually not" for -dealloc.
When initializing an object, you want to make sure to properly copy/retain values for ivars. Unless the property's setter has some side effect that makes it inappropriate for initialization, definitely reuse the abstraction the property provides.
When deallocating an object, you want to release any ivar objects, but not store new ones. An easy way to do this is to set the property to nil (myObject.myIvar = nil), which basically calls [myObject setMyIvar:nil]. Since messages to nil are ignored, there is no danger in this. However, it's overkill when [myIvar release]; is usually all you need. In general, don't use the property (or directly, the setter) in situations where deallocation should behave differently than setting the variable.
I can understand eJames' argument against using property accessors in init/dealloc at all, but the flipside is that if you change the property behavior (for example, change from retain to copy, or just assign without retaining) and don't use it in init, or vice versa, the behavior can get out of sync too. If initializing and modifying an ivar should act the same, use the property accessor for both.
If so, why is this different? Is it just because the compiler can't see the ivar?
The modern runtime deals with class size and layout more intelligently, which is why you can change the layout of ivars without having to recompile subclasses. It is also able to infer the name and type of the ivar you want from the name and type of the corresponding property. The Objective-C 2.0 Runtime Programming Guide has more info, but again, I don't know how deeply the details explained there.
If I need to override an accessor, can I still access that iVar that will be defined at runtime or do I have to define an actual iVar that the runtime will then use?
I haven't tested this, but I believe you're allowed to access the named ivar in code, since it actually does have to be created. I'm not sure whether the compiler will complain, but I would guess that since it will let you synthesize the ivar without complaining, it is also smart enough to know about the synthesized ivar and let you refer to it by name.
Again, if I can access the synthesized iVar, why can't I continue to do this for the init* and dealloc methods?
You should be able to access the property and/or ivar anytime after the instance has been allocated.

There is another SO question with similar information, but it isn't quite a duplicate.
The bottom line, from the Objective-C 2.0 documentation, and quoted from Mark Bessey's answer is as follows:
There are differences in the behavior that depend on the runtime (see also “Runtime Differences”):
For the legacy runtimes, instance variables must already be declared in the #interface block. If an instance variable of the same name and compatible type as the property exists, 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.
My understanding is as follows:
You should not use property accessors in init* and dealloc methods, for the same reasons that you should not use them in the legacy runtime: It leaves you open to potential errors if you later override the property methods, and end up doing something that shouldn't be done in init* or dealloc.
You should be able to both synthesize the ivar and override the property methods as follows:
#interface SomeClass
{
}
#property (assign) int someProperty;
#end
#implementation SomeClass
#synthesize someProperty; // this will synthesize the ivar
- (int)someProperty { NSLog(#"getter"); return someProperty; }
- (void)setSomeProperty:(int)newValue
{
NSLog(#"setter");
someProperty = newValue;
}
#end
Which leads me to think that you would be able to access the synthesized ivar in your init* and dealloc methods as well. The only gotcha I could think of is that the #synthesize line may have to come before the definitions of your init* and dealloc methods in the source file.
In the end, since having the ivars declared in the interface still works, that is still your safest bet.

I am running into the same problem. The way I am working around not being able to access the synthesized instance variables is the following:
public header
#interface MyObject:NSObject {
}
#property (retain) id instanceVar;
#property (retain) id customizedVar;
#end
private header / implementation
#interface MyObject()
#property (retain) id storedCustomizedVar;
#end
#implementation MyObject
#synthesize instanceVar, storedCustomizedVar;
#dynamic customizedVar;
- customizedVar {
if(!self.storedCustomizedVar) {
id newCustomizedVar;
//... do something
self.storedCustomizedVar= newCustomizedVar;
}
return self.storedCustomizedVar;
}
- (void) setCustomizedVar:aVar {
self.storedCustomizedVar=aVar;
}
#end
It's not that elegant, but at least it keeps my public header file clean.
If you use KVO you need to define customizedVar as dependent key of storedCustomizedVar.

I'm relatively new to Obj-C (but not to programming) and have also been confused by this topic.
The aspect that worries me is that it seems to be relatively easy to inadvertently use the iVar instead of the property. For example writing:
myProp = someObject;
instead of
self.myProp = someObject;
Admittedly this is "user" error, but it's still seems quite easy to do accidentally in some code, and for a retained or atomic property it could presumably lead to problems.
Ideally I'd prefer to be able to get the runtime to apply some pattern to the property name when generating any iVar. E.g. always prefix them with "_".
In practice at the moment I'm doing this manually - explicitly declaring my ivars, and deliberately giving them different names from the properties. I use an old-style 'm' prefix, so if my property is "myProp", my iVar will be "mMyProp". Then I use #synthesize myProp = mMyProp to associate the two.
This is a bit clumsy I admit, and a bit of extra typing, but it seems worth it to me to be able to disambiguate a little bit more clearly in the code. Of course I can still get it wrong and type mMyProp = someObject, but I'm hoping that the 'm' prefix will alert me to my error.
It would feel much nicer if I could just declare the property and let the compiler/runtime do the rest, but when I have lots of code my gut instinct tells me that I'll make mistakes that way if I still have to follow manual rules for init/dealloc.
Of course there are also plenty of other things I can also do wrong...

Related

Modern Objective-C (2013) and declaring ivars/using #property, #dynamic, and #synthesize

With the current version of Objective-C, what are the official standards and best practices for declaring ivars, using #property and #synthesize? There are a lot of posts and resources on the topic but most of them are fairly antiquated from a year or two ago. I recently learned to only declare ivars in a statement block in the implementation of a class so that the encapsulation principles of OOP aren't broken but is declaring ivars even necessary in this day and age? What would be a possible use case where doing:
#interface MyClass()
#property (nonatomic) NSString* data;
#end
#implementation MyClass{
#private
NSString* _data;
}
#end
is necessary? To further that, is it ever necessary to use #synthesize? My understanding is that using #property will auto-synthesize both the accessor methods as well as the backing ivars. I've done some experimentation and I noticed that when I don't declare NSString* _data', I can still access_data' in my class implementation. Does that mean that declaring ivars come down to a matter of style, up to the discretion of the programmer? Could I condense my code and remove all ivar declarations in the statement blocks in my implementation and just use #property in my private interface? If that's not the case, what are the advantages and disadvantages of explicitly declaring ivars?
Finally, #dynamic. From what I can gather, it's used to say to the compiler, "Hey compiler, don't auto-generate the accessor method and don't worry if you don't find an implementation for it, I'll provide one at runtime". Is that all #dynamic is used for or is there more to it?
I just want to clarify all these things because it seems like there's a lot of different opinions and that there's not necessarily one right answer. Plus as Objective-C grows and progresses, those answers will change so it'll be nice to have a concise and up-to-date guide. Thanks everyone!
(Also if there's anything that I could word better or make clearer, let me know)
EDIT:
In summary, what I'm asking is this:
1) Is declaring ivars with modern Objective-C necessary?
2) Can I achieve the same effects of declaring ivars and corresponding properties by just using #property?
3) What is #dynamic used for?
4) Can I completely forgo the use of #synthesize or is there a good use case for it?
Upvote and down vote as you see fit.
There's a lot to answer here. I'll break it down:
Declaring ivars
As you've correctly noted, modern versions of the compiler will synthesize backing instance variables for declared #properties. The exception to this is on 32-bit Macs, where the modern Objective-C runtime, including non-fragile instance variables, is not available. Assuming your application is not targeting 32-bit OS X, you don't need to explicitly declare the backing ivar for an #property.
If you still want to use an ivar directly, without a corresponding #property (something I consider a bad idea most of the time), you of course must still explicitly declare the ivar.
#dynamic
#dynamic is as you've said meant to tell the compiler "don't synthesize accessors for this property, I'll do it myself at runtime". It's not used all that often. One place it is used is in NSManagedObject subclasses, where if you declare a modeled property in the header, you don't want to compiler to complain that there's no implementation of accessors for that property, nor do you want it to generate accessors itself. NSManagedObject generates accessors for modeled properties at runtime. The story is similar for custom CALayer subclasses.
#synthesize
#synthesize explicitly tells the compiler to synthesize accessor methods, and (on iOS and 64-bit Mac) a corresponding ivar for the specified property. There are three main cases where you still need to use it:
32-bit Mac apps.
If you've written your own custom setter and getter (or just getter for readonly properties). In this case, the compiler won't synthesize accessors because it sees yours. However, it also won't synthesize the backing ivar. So, you must use #synthesize someProperty = _someProperty;, to tell the compiler to synthesize an ivar. It still won't synthesize accessor methods of course. Alternatively, you can explicitly declare a backing ivar. I favor using #synthesize in this case.
If you want to use a different name for the property's backing ivar than the default (property name with an added underscore prefix). This is rare. The main case I can think of for using it is when transitioning existing, older code, that includes direct ivar access and where the ivars are not underscore-prefixed.
Best current practice seems to be to use properties for all ivars placing the property either in the .h file if they are to be exposed and in the .m file in a class extension if local to the class.
No #synthesize is needed unless the ivar needs to be different than the underscore prepended property name.
Yes, #dynamic is as you describe.
Further, it is no longer necessary to declare local instance methods or order such that the method is above the use.
First off, #synthesize is gone for these scenarios: do not have to do it any more.
Secondly, you don't need the private ivar anymore either.
So in essence, you can just do properties.
The way of controlling access is the same idiom that had become popular before MOC dropped: put the property in the public interface as readonly and then make a readwrite version in the private interface (which should be, as you show above, merely the name with open and close parens).
Note also, that many of the things that cluttered up the public interface in the past can now ONLY be in the private interface, so for instance IBOutlets, etc., since the controller is going to be the only thing diddling them.
I never see #dynamic used anywhere except in CoreDate-generated entities.
For someone who first worked with C++ where the dream was always that the header/interface merely show the user of the class what they needed and all other details would be hidden, I think MOC (Modern Objective C) is a dream come true.
BTW, highly recommend the intro session from WWDC Modern Objective C (from 2012) and the one this year was great too.

self.variableName vs. _variableName vs. #sysnthesize variableName [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does an underscore in front of a variable in a cocoa objective-c class work?
Note: For the folks digging around trying to understand this, I figured-out the source of my confusion. In the .h, I had:
...
#interface myClass : parentClass {
className *variableName:
}
#property (strong, nonatomic) className *variableName;
...
This leads to self.variableName and _variableName being two distinct variables in the .m. What I needed was:
...
#interface myClass : parentClass {
className *_variableName:
}
#property (strong, nonatomic) className *variableName;
...
Then, in the class' .m, self.variableName and _variableName are equivalent
In brand-new, Xcode 4.5+, with ARC, targeting iOS 5.0+ project, is there a distinct advantage (runtime efficiency, speed, etc.) to using _variableName over self.variableName vs. the old-style #synthesize variableName?
My understanding is that Xcode 4.5+ will create a default accessor _variableName that is equivalent to self.variableName and the only reasons not to use #synthesize variableName is to avoid confusion between iVars and passed-in variables, correct?
To me, just using self.variableName to access an iVar seems the most straightforward and clear as to which variable you're looking for. Other than typing _ vs. self., is there an advantage to using _variableName?
My understanding is that Xcode 4.5+ will create a default accessor "_variableName" that is equivalent to self.variableName and the only reasons not to use "#synthesize variableName" is to avoid confusion between iVars and passed-in variables, correct?
In this case, _variableName isn't the accessor, it's an ivar that is automatically generated by the compiler and used in the automatically #synthesized setters and getters. Generally, it is considered best to use accessors whenever possible (i.e. self.variableName) so that things like key-value observation and bindings work for that property.
When you access an ivar directly, it is accessed via direct memory access, the same way you would access data in a struct. It simply takes the pointer for the object that owns the ivar, offsets the memory address and attempts to read or write to the memory at that location. Using dot notation (self.variableName) calls the accessor methods to set or get that property and can do a number of different things along the way, such as:
1) Locking: If the property is going to be used in multiple threads and is an atomic property, the runtime will automatically do some locking to make sure that the property is not accessed at the same time from multiple threads. If your object is not meant to be used on multiple threads, you can give the nonatomic hint in your property declaration so that the synthesized accessors skip the locking.
2) Key-Value Notifications: The default setters for properties call -willChangeValueForKey: and -didChangeValueForKey:, which sends out notifications when the property is changed. This is necessary for anything to update properly if bindings are used, and for any other key-value observation.
3) Custom accessor behavior: If you end up writing your own setters and getters, any custom stuff that you implement within those.
Technically, accessing the ivar directly is faster than using accessors, but there are very few situations in which it will make a significant performance difference, and would probably be a case of premature optimization. Even if you don't feel like you would be using the benefits listed above right away, it's probably better to use the accessors anyway so that if you decide later on you need some of that functionality, you don't have to change every instance of accessing that variable (and possibly be creating unexpected new bugs in the process).
In addition, if you are accessing ivars directly and end up refactoring your class into categories or subclasses, it gets messy because you usually have to declare the ivar as a #protected variable. You wouldn't have to do this if you are using the accessors.
Generally, I try to only access the ivars directly in init, dealloc, and the property's accessor. A lot of engineers go by this rule of thumb because sometimes the custom stuff that happens in accessors can cause unexpected behavior while the object is init'ing or dealloc'ing. For example, if anything in the accessors causes something to retain or release your object or even form a zeroing weak reference to it, it will cause a crash if used in dealloc.
In the latest Xcode #synthesize is optional. By default, omitting #synthesize is the same as writing
#synthesize someName = _someName;
The only reason to use #synthesize is to rename the instance variable created to store the value of the property, for example
#synthesize someName = someSpecialName;
When you use self.variableName to access a variable, you go through a property, which is a short method that accesses the instance variable for you. Although the method dispatch is very fast, it may perform additional services for you, such as synchronizing the access to the variable (this is the case when you specify atomic or do not specify nonatomic in the property declaration). In cases like that, the access through self.variableName will be somewhat slower. If done in a tight loop, this could potentially make a difference. That is why you sometimes want to access the underlying instance variable directly by using _variableName.

"property is backed by an ivar" ? What technically does that mean?

So ... I'm still fairly new to Objective C ... taking some iTunes U corses ... doing some exercises and all ...
But when you uses to do #synthesize myProperty = _myIvarPropertyNameToUse; ... iOS 5 would create an ivar that would "back" the property.
What exactly is going on here as far as where things sit in memory ...
(1) Is the ivar a true variable? ... or is it a pointer to the location of the property in the object?
(2) The property is on the heap, (being part of the object), right? Is the ivar on the heap as well?
I think I may be losing the big picture ... what's the point of having a property backed by an ivar?
thanks,
An Objective-C object is just a C struct that is allocated on the heap (well, more or less). When you declare an instance variable (ivar), it is defined as an offset into that struct. So if you manually declared some ivars like this (don't do it this way anymore, but it illustrates the point):
#interface Foo : NSObject {
NSString *ivar1;
NSString *ivar2;
}
Then when you +alloc a new instance (call it foo), the struct will be some header followed by the ivars of NSObject followed by memory for ivar1 followed by memory for ivar2. ivar1 will be the foo point plus some offset. (This isn't exactly true anymore, but stay with me; it's simpler to understand the old implementation.)
Since foo is a pointer to a struct, you can actually refer directly to this offset pointer as foo->ivar1. It really is a struct. Never do this, but it is legal syntax.
Inside of the #implementation block, ivar1 is automatically translated to self->ivar1. Don't worry too much about how self is implemented, but trust that it's a pointer to your struct. Again, never use this -> syntax. It's an underlying implementation detail (and isn't always possible anymore; see below).
OK, so that's what an ivar is. In the old days (ObjC 1.0), that's actually all we had. You declared your ivars, and then you hand-created accessor methods that would set and return their values.
Then ObjC2 comes along, which in some cases also gave us something called the non-fragile ABI. That changes the underlying implementation of ivars somewhat, so you can't always actually use -> anymore. But you shouldn't have been using it anyway. Even so, it's simpler to pretend things are the old way. More to the point, ObjC2 added this new thing called "properties." A property is just a promise to implement certain methods. So when you say:
#property (nonatomic, readwrite, strong) NSString *property;
this is almost identical to saying the following:
- (NSString *)property;
- (void)setProperty:(NSString *)aProperty;
(The difference is very seldom important.) Note that this doesn't provide an implementation. It doesn't create ivars. It just declares some methods.
Now in ObjC1, we wrote the same accessor code over and over and over again. You had 20 writable ivars, you wrote 40 accessor methods. And they were almost identical. Lots of opportunities to mess up. And a lot of tedium. Thank goodness for Accessorizer.
With ObjC2, the compiler would give you the most common implementation for free if you added #synthesize. It would automatically make an ivar with the same name as the property, and write a getter and (if needed) setter to read and write that ivar. Passing =_property just changes the name of the ivar used. We call this the "backing ivar."
Now, in the latest version of the compiler, you don't even need #synthesize. This pattern is so insanely common, and has been for decades, that it is now the default unless you tell the compiler not to do it. And it automatically synthesizes an ivar with a leading underscore (which is best practice).
The one other piece of information you should know is that you should always use the accessor to access the ivar, even inside of the object. The only exceptions are in the init and dealloc methods. There you should directly access the ivar (using the leading underscore).
Just to be clear, when you do #synthesize myProperty = _myIvarPropertyNameToUse;, your only changing the name of the backing ivar. The line #synthesize myProperty; would also create a backing ivar, but it would be called myProperty, instead of _myIvarPropertyNameToUse...
The backing ivar is part of the object, so yes it's on the heap. It can be used as a true variable, meaning you can get and set it in the object code.

Objective-C coding guidelines

So in the guidelines it says:
For code that will run on iOS only, use of automatically synthesized instance variables is preferred.
When synthesizing the instance variable, use #synthesize var = var_; as this prevents accidentally calling var = blah; when self.var = blah; is intended.
// Header file
#interface Foo : NSObject
// A guy walks into a bar.
#property(nonatomic, copy) NSString *bar;
#end
// Implementation file
#interface Foo ()
#property(nonatomic, retain) NSArray *baz;
#end
#implementation Foo
#synthesize bar = bar_;
#synthesize baz = baz_;
#end
Question is, does this apply to public variables only or private too? It's not really clear on the documentation, but would like to have some thoughts or perspective on why "if" this is only for public or private only? I think that it just makes sense for all public/private so that you don't mess up ivars and using the property
I don't think it particularly matters whether the variables in question are public or private. The practice of synthesizing under a different name makes it explicit when you are accessing the variable directly instead of using the generated accessor method.
Perhaps there's a different question underlying what you're asking: should I typically access private ivars via the accessor or directly? I think most skilled iOS devs tend to use accessors unless there is some particular reason not to (performance, avoiding side effects like KVO, etc.). Doing so is more future-proof and allows for flexibility in the underlying implementation. In a very small way, you're coding to an interface rather than an implementation.
It also might be worth pointing out that the default behavior of Clang is going to change in the future so that property-backing ivars are synthesized named _foo by default. Clearly the powers-that-be consider consider underscoring ivars to be a best-practice.
I am pretty sure much of it comes down to personal preferences, so here are mine, for what they are worth:
I like to distinguish between public properties and "private" instance vars.
Properties are always accessed through their accessors, except for initialization (and within a manually created accessor method, for obvious reasons). Hence, the underscore in the backing ivar is useful, and not really an issue in my daily use of the properties.
Instance vars are used to hold state that is used internally in the methods, but not (directly) by other classes.
I have become very fond of declaring my instance variables in the .m file. Nice, clean and easy (no switching back and forth between .h and .m to declare ivars).
I find that this distinction helps me clear my mind and determine if a property is something outside agents should get and/or set directly (a property in .h), or if it is really just a help to get my method implementations to work (an ivar in .m).
I'd agree with Paul.s. that consistency is your friend, but to me, distinction is a friend, too.

Adding Member Variables in Objective C

First I have to do
#property (retain) aMember;
Then in implementation file I got to do
#synthesize aMember;
Then in dealloc, I got to do
self.aMember= nil; (or [aMember release])
That's 3 times writing what essentially is the same
Is there a way to speed this up?
I mean I can drag drop a control from a IB and xcode automatically generate those codes why I can't do that for more normal codes?
As someone coming from C# and managed languages for my day job I completely agree with you in questioning this 3 step process. In fact its almost crazy easy to create properties in C# in MS Visual Studio, but I digress.
Even though there are these 3 lines you have to write there is a huge amount of work going on under the covers for your.
Your declaration of the #property tells objective-c some important attributes (atomic, nonatomic, retain, copy, etc) in how to deal with your property when it is set by users of your class. When you think about this, these attributes (without you writing any code) are; helping you create thread safe code, handling references to objects so you don't have to worry about them disappearing on you, or copying values so you have your own copy of an object. The #property is also important since it is declared in your header file (typically). This give other developers an idea of the properties of your class and some small hints as to how objects they pass into those properties will be handled during its lifetime.
The #synthesize is also doing quite a bit of work by creating the getters and setters for that property, that also handle all sorts of memory management for you. You don't need to worry about releasing the old references and correctly referencing the new object. This alone to me is a great feature, especially when you are new to objective-c and it is easy to forget to deal with memory management at every turn. The #synthesize just does it for you and you don't have to write all the get and set code yourself.
The dealloc call is just life in a non-memory managed environment. While it adds additional steps, I appreciate the benefits that explicit memory management allows in a constrained environment such as the phone.
So all 3 steps are required, are different and when you think about it actually do quite a bit of work for you under the covers.
Unfortunately, that's how it is (for now). Apple had recently toyed with allowing Clang to implicitly synthesize your properties, which would have reduced your work to:
#interface Blah : NSObject
#property (retain) Blorg *blorg;
#end
#implementation Blah
- (void)dealloc {
[blorg release];
[super dealloc];
}
#end
When you didn't want an instance variable to be synthesized, you'd just explicitly put #dynamic blorg in your implementation. But this feature was removed due to some unforeseen complications, despite mostly positive reactions from developers.
So, I think it's safe to expect that Apple's still working on this. But for now, you do need to explicitly synthesize.
A few other notes:
If you are using garbage collection, you don't need to implement -dealloc: just make sure to do any last-minute cleanup in -finalize (such as notification unregistration).
You could also avoid the -dealloc bit by wrapping your instance variable in a C++ class which performs memory management during construction and destruction: #property prop_wrapper<Blorg> blorg; would work. Then, when your object is destroyed, ~prop_wrapper() would be called on your object. I've done this, and it works, but I recommend against it, since it doesn't play nice with KVO and KVC.
You could iterate through the properties of an object, and release those that are annotated with copy or retain. Then, in -dealloc, you'd have something like [self releaseProperties]. I've also done this, but I also recommend against it, since it can cause subtle problems which may result in inexplicable crashes if you're not careful.
To actually add a member variable in objective-c you don't need to do any of that.
What you're doing in those 3 steps is:
Declare properties for a member variable. (In your case you are indicating that you want the property setter to 'retain' the object that it sets your member variable to)
Declare the property getters and setters in a default way for your property.
Release the object that your property is retaining.
IF you only wanted to declare a member variable, all you had to do was declare it inside your class:
#interface SomeClassObject : NSObject {
int someMemberVariable;
}
#end
That's 3 times writing what essentially is the same
No it isn't.
#property (retain) aMember;
The above line declares a property so that the compiler knows it is OK to send the messages -aMember and -setAMember: to objects of your class. It also tells the compiler (and developers) that the property is a retain property (i.e. the object you set the property to will be retained), that it is read/write and that it is atomic.
#synthesize aMember;
The above line tells the compiler that it should automatically generate the setter and getter methods for the declared property. You can leave that out but then you have to write your own setter and getter.
[aMember release]; // in dealloc
Is there to tell the runtime that when the object is being deallocated, it no longer needs to hold a reference to that instance variable. This is necessary because, when you use reference counting rather than garbage collection, the runtime does not automatically clean up unwanted objects.
Each of those lines does a different thing. So you are not doing the same thing three times.