深刻理解属性:getter及setter -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

    对于有Mac开发经验的iPhone开发者,可能对O-C的注解"@property"已经习以为常了,

深刻理解属性:getter及setter

。但对于从其他开发平台(Java或者Symbian)迁移过来的iPhone开发者,"@property"仍然有点麻烦。为了使这些人不再犯我一样的错误,本文简单探讨了变量及属性,以及它们所采用的内存管理

    首先来看一个简单类:

    //MyClass.h file

    @interface MyClass: NSObject

    {

    NSString *text;

    }

    -(void) init;

    -(void) logText;

    @end

    //MyClass.m file

    @implementation MyClass

    - (void)init

    {

    text = @\"sometext\";

    }

    - (void)logText

    {

    NSLog(@\"%@\", text);

    }

    @end

    这个类十分简单。它唯一的成员就是text,一个NSString.text变量在init方法中初始化,在logText方法中被引用。

    就目前而言,text变量中存储的是常量值,我们无须关心它的内存管理。但在真正的程序中,我们可能会想在运行时改变text的值,因此需要为它设计getter和setter方法:

    //MyClass.h file

    @interface MyClass: NSObject

    {

    NSString *text;

    }

    -(void) init;

    -(void) logText;

    -(NSString*) text;

    -(void) setText:(NSString *)textValue;

    @end

    //MyClass.m file

    @implementation MyClass

    - (void)init

    {

    text = @\"sometext\";

    }

    - (void)logText

    {

    NSLog(@\"%@\", text);

    }

    -(NSString*) text

    {

    return text;

    }

    -(void) setText:(NSString *)textValue

    {

    if (textValue !=text)

    {

    [textValue retain];

    [text release];

    text = textValue;

    }

    }

    -(void)dealloc

    {

    [text release];

    [super dealloc];

    }

    @end

    接下来,我们需要:

    一、添加一个方法,读取当前的text属性:

    NSString *theTextValue = [obj text];

    (假设 "obj" 是一个MyClass实例)

    这个方法很简单 - 仅仅是返回text属性值。

    二、在另一个方法中,改变text属性:

    [obj setText:newStringValue];

    (假设 "obj" 是一个MyClass实例, "newStringValue" 是一个 NSString)。

    在setText:方法中,由于我们无法确定newStringValue到底是不是一个常量--它可能是任何NSString值,包括在堆中分配的NSString.因此,我们要"retain"这个(将要赋值给text的)对象,以确保这个对象能够和MyClass对象的生命周期一样长。同样,对于已经被替换掉的旧有值,我们不应当再持有它,因此我们释放了它。if语句的使用,是为了减少不必要的赋值--当然,你也可以不用它:

    -(void) setText:(NSString *)textValue

    {

    [textValue retain];

    [text release];

    text = textValue;

    }

    即使textValue和text值相同,代码也会被执行,因为我们先在引用计数器上+1,然后再减1.注意,这种写法是错误的:

    -(void) setText:(NSString *)textValue

    {

    [text release];

    [textValue retain];

    text = textValue;

    }

    这是因为,当"输入"值和要"持有"的值指向了同一个NSString的情况下,会导致字符串最终将被deallocated--第1句代码有可能将引用计数减为0,导致对象被仍会堆里,

电脑资料

深刻理解属性:getter及setter》(https://www.unjs.com)。第2句代码试图去retain这个已经释放的对象(由于二者是同一个)。这种情况不一定发生,但却是一个隐患。

    最后,我们实现dealloc方法,在其中释放text对象。我们既然retain了某些东西,就需要记得release它,就好比人临死的时候,要记得把借的书还给图书馆。

    值得注意的是,进行空赋值这些代码仍然工作得很好。O-C有个奇怪的特点,允许向nil发送消息(比如release和retain消息)而不会出任何错误。类似于++ 中可以释放一个null指针。

    现在,更有趣的事情来了。我们将加入第2个成员变量,以及它的getter和setter.很快你就会看到将发生什么。

    //MyClass.h file

    @interface MyClass: NSObject

    {

    NSString *text;

    int value;

    }

    -(void) init;

    -(void) logText;

    -(NSString*) text;

    -(void) setText:(NSString *)textValue;

    -(int) value;

    -(void) setValue:(int*)intValue;

    @end

    //MyClass.m file

    @implementation MyClass

    - (void)init

    {

    text = @\"sometext\";

    value = 2;

    }

    - (void)logText

    {

    NSLog(@\"%@\", text);

    }

    -(NSString *) text

    {

    return text;

    }

    -(void) setText:(NSString *)textValue

    {

    if (textValue !=text)

    {

    [textValue retain];

    [text release];

    text = textValue;

    }

    }

    -(int) value

    {

    return value;

    }

    -(void) setValue:(int)intValue

    {

    value = intValue;

    }

    -(void)dealloc

    {

    [text release];

    [super dealloc];

    }

    @end

    这次,我们简单地加入了一个整型变量以及setter/getter方法。但这次,我们不需要retain 和release .因为整型不是在堆中分配的-它直接存储在MyClass中。我们可以这样干:

    NSString *s = [objtext];

    [objsetText:@\"new string\"];

    int i = [obj value];

    [obj setValue:3];

    现在,类似的getter/setter方法在O-C中实在是多得让人写不胜写。因此O-C也提供了更简单的方式为我们自动生成这些方法。我们可以将上述代码修改为:

    //MyClass.h file

    @interface MyClass: NSObject

    {

    NSString *text;

    int value;

    }

    @property(nonatomic, retain) NSString *text;

    @property(nonatomic, assign) int value;

最新文章