开发者

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.

  1. 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.

  2. 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.

  3. 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:

  1. 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).

  2. 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.

  3. 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:

  1. 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)

  2. Declare the property getters and setters in a default way for your property.

  3. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜