开发者

When would a instance variable be used and when would a property be used?

In a header file such as this, when would an instance variable be used and when would a property be used?

Do they have to have the same name?

#import <开发者_高级运维;UIKit/UIKit.h>

@class BlueViewController;
@class YellowViewController;

@interface SwitchViewController : UIViewController {
    YellowViewController *yellowViewController;
    BlueViewController *blueViewController;
}

@property (retain, nonatomic) YellowViewController *yellowViewController;
@property (retain, nonatomic) BlueViewController *blueViewController;

@end


A @property declaration simply creates accessor methods for an ivar. So properties don't really have names, only the accessor methods do; and these don't have to have the same name as the ivar. In fact, they don't even have to have a corresponding ivar.

You can change the names of the methods using the getter and setter decorators like this:

@property (assign, getter=isValid) BOOL valid;

Now, as I said, a @property declaration simply creates accessor methods for an ivar. So you use properties when you want accessor methods. Here are a few reasons why you might want accessor methods:

  1. Encapsulation (a property might be advertised as a different type than the ivar, or might not even have an ivar)

  2. Related state changes (change another ivar or invoke a method when an ivar is modified)

  3. You can use the retain decorator and @synthesize the property to get much simpler memory management

  4. You can use atomic decorator (or simply not use the nonatomic decorator, since properties are atomic by default) to create atomic properties

Here's an example to demonstrate points 1 and 2:

@interface Foo : NSObject {
    @private
    int flags;
    // Humpty and Dumpty are mutually exclusive
    BOOL humpty;
    BOOL dumpty;
}

@property (nonatomic) BOOL flagA;
@property (nonatomic) BOOL flagB;
@property (nonatomic) BOOL humpty;
@property (nonatomic) BOOL dumpty;
@property (nonatomic, readonly, getter=isClean) BOOL clean;

@end

@implementation Foo

@synthesize humpty, dumpty; // Synthesize the getters, but provide the setters

- (void)setHumpty:(BOOL)value {
    if(value && dumpty)
        dumpty = NO;

    humpty = value;
}

- (void)setDumpty:(BOOL)value {
    if(value && humpty)
        humpty = NO;

    dumpty = value;
}

- (BOOL)flagA {
    return flags & 0x01;
}

- (void)setFlagA:(BOOL)value {
    if(value)
        flags |= 0x01;
    else
        flags &= ~0x01;
}

- (BOOL)flagB {
    return flags & 0x02;
}

- (void)setFlagB:(BOOL)value {
    if(value)
        flags |= 0x02;
    else
        flags &= ~0x02;
}

// Making this a property doesn't really make sense
// but I'm just trying to demonstrate what you can do
// with properties
- (BOOL)isClean {
    return flags == 0;
}

@end


You want to use the properties for all your external access to provide encapsulation, it's up to you whether you want to use them internally though, i think it's a matter of taste.

By using the properties from outside of your class you can for example do some lazy loading and it becomes a lot easier to make any potential API changes by providing deprecation warnings in the getters/setters.


They can have the same name, although they don't have to. Indeed, it's not required for the externally-visible property to correspond exactly to a single instance variable at all. Such a correspondence is expected if you're going to @synthesize the accessor methods, but there are quite legitimate reasons for creating the methods manually and making them do something other than just getting/setting a matching ivar.

Instance variables are normally not accessible from the outside world, so all external access has to be via the property methods. (It is possible to declare ivars @public, but this is rarely a good idea.)

From within the object, whether you access as properties or instance variables depends on what the properties actually are and what you're doing with them.

For simple synthesized properties it is common to use the accessors (either explicitly using [self setXxx] or using the dot notation as self.xxx) except within dealloc (and possibly init, depending on who you ask).

In more complex cases, you really have to think about what it is you are trying to achieve. But if you've gone to the trouble of making them properties you probably want whatever functionality is encapsulated in the accessor methods to be called most of the time.

At any rate, read the properties documentation to get a better understanding of what's going on.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜