In my code, every time I need a new object attribute for my class, I typically copy/paste its name in 4 different places!
- The declaration in the header file (
NSObject * myObject;
) - The
@property()
line - The
@synthesize()
line in the implementation - Releasing it under
dealloc:
(only for objects of course)
I do this because it works, not because I completely understand what's going on. I do know that the declaration in the header file allows other classes to see its attributes, the property specifier determines how its getter/setter methods will be constructed. And the synthesize line actually builds those getter/setter methods. I also know that primitive types should use (nonato开发者_开发知识库mic,assign
) instead of (nonatomic,retain
), but I have no clue when I should omit the nonatomic.
What can I do to avoid redundancy in my code. If I change or add a variable in my class I have to check 4 different places, and it gets old really fast. Are there any key strokes to make this process faster? Are there lines of code I can simplify or combine to obtain the same result?
Accessorizer will automate a lot of this for you.
In the latest version of Clang (Ships with XCode 4, not in XCode 3 yet) you get default @synthesize as well as default ivar creation. The default ivar creation already works, but not on the simulator. With both of these features all you need to do is add the @property line and deal with the memory management in dealloc
As far as nonatomic vs atomic. atomic is the default, and what happens when you leave off the nonatomic annotation. Atomic guarantees that the value is completely set before allowing anything to access it, nonatomic doesn't. Atomic is only useful in threading situations, and is slightly slower in singlethreaded applications.
It's important to understand what each of those lines of code does. They are not all the same and they are not necessarily redundant. One thing that will help is to use the correct terminology — for example, with NSObject *myObject;
you're probably referring to an instance variable declaration.
First and foremost, a @property
declaration in an @interface
lets you say that instances of a class expose a piece of state. It doesn't say much about the implementation of that state, only that it's exposed by instances of your class and the API contract (memory management, atomicity, methods) for the state.
The @synthesize
directive tells the compiler to create or use a specific instance variable as storage for a declared @property
. This does not need to be how you provide storage for a property. For example, Core Data provides its own storage for modeled properties, so you use @dynamic
for those instead. You also don't need to use an instance variable with the same name as your @property
— to extend your example above, you might name your instance variable myObject_
while naming your property object
and that's perfectly fine.
Finally, you send the instance variable -release
in -dealloc
— for an object-type property marked retain
or copy
— because you've said you'll manage its memory. You're not releasing the property, you're releasing the storage. If you implemented the storage some other way, you'd clean it up some other way.
精彩评论