Cocoa's Objective-C中的retain property

如果在一个Objective-C类中定义一个retain属性的property,只有使用obj.var的形式去访问时才能使属性生效,即使用该成员变量的getter/setter方法,否则无法使得此属性生效,比如:

#import <Foundation/Foundation.h>

@interface MyController : NSObject
{
    NSString *ms;
}

@property(retain) NSString *ms;

- (IBAction)buttonPressed:(id)sender;

@end

我们先用访问属性的方式来访问ms成员变量:

#import "MyController.h"


@implementation MyController

@synthesize ms;

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
    }
    
    return self;
}


- (IBAction)buttonPressed:(id)sender
{
    NSString *s = [[NSString alloc] initWithFormat:@"Hello"];
    
    self.ms = s;
    
    [s release];
    
    NSLog(@"The content is: %@", ms);
}

@end

这段程序将会非常正常地执行。尽管s在赋给self.ms后就调用了release方法,但由于self.ms的属性是retain,所以将s的字符串对象的引用计数加1,这样就把这个对象给保留住了。

如果我们将第23行改为:

ms = s;

那这段程序执行到NSLog就会崩溃。因为这里没有用ms的setter方法,retain属性没有生效。而此时s已经被释放,因此ms也就指向了一个无效对象。