目标C - 用setter和w / o setter改变局部变量

时间:2012-12-25 03:52:59

标签: objective-c setter

  

可能重复:
  Difference between self.ivar and ivar?

在Objective-C中,[self setVariable: newStuff]variable = newStuff之间有什么区别?

当你有一个带变量

的类时
@property (nonatomic) NSInteger num;

并且您想要更改变量,通常可以执行

[self setNum: newNum]

但你也可以

num = newNum

我知道如果你声明变量readOnly,你不能使用第一种方法来改变它,但它背后的概念是什么?是否只是因为setter的第二个方法可以在它自己的类之外调用?就像类的实例被称为'sample'一样。

[sample setNum: newNum]

但是如果你要更改类中的变量,那么两种方式都可以吗?

3 个答案:

答案 0 :(得分:2)

  

在Objective-C中,[self setVariable:有什么区别?   newStuff]和variable = newStuff?

绝对迂腐,其中一个为variable属性赋予newStuff中的值,而另一个属性将newStuff的值赋给iVar variable,但我认为你想到的是[self setVariable: newStuff]self.variable = newStuff之间的比较。在这种情况下,没有什么不同,编译器会将案例2扩展到案例1。

  

我知道如果你声明变量readOnly,你不能使用第一个   改变它的方法,但背后的概念是什么?它只是   因为setter的第二个方法可以在其外部调用   自己上课?就像类的实例被称为'sample'一样。

readonly变量在某些属性对于类的实现是私有的情况下很重要,但对于其他类应该是可见的。

例如,如果我正在编写一个Stack,我可能想要公开堆栈中项目数的计数,但是其他类能够写入count变量是一个非常糟糕的主意。如果我不聪明并且使用类似计数变量的东西,我希望能够在内部调整信号量的数量(意味着你需要它在内部进行读写),所以我声明了一个明显的readonly属性,所以其他类可以得到它,但声明它在内部读写所以我可以修改它:

//.h
@interface CFExampleStack : NSObject 

@property (nonatomic, assign, readonly) int count; //readonly

@end

//.m
@interface CFExampleStack ()

@property (nonatomic, assign) int count; //readwrite

@end

答案 1 :(得分:1)

  

是否只是因为setter的第二个方法可以在它自己的类之外调用?

那么,这取决于你的实例变量的声明方式。默认情况下,实例变量为@protected,i。即它们只能从类及其子类中访问。但是,如果您明确地将ivar声明为@public,那么您可以使用C结构指针成员运算符->在类外部访问它:

obj->publicIvar = 42;

但是,不建议这样做,因为它违反了封装。

此外,如果使用自定义setter方法,则可以在更新实例的属性时执行自定义操作。例如,如果更改backgroundColor的{​​{1}}属性,除了将新的UIView对象分配给其相应的ivar之外,还需要重绘自身,为此,需要自定义setter需要实施副作用。

此外,在保存对象的实例变量的情况下,保留(“强”)和复制属性。为原始类型(如整数)编写setter时,就像

一样简单
UIColor
相反,保留或复制的属性需要适当的内存管理调用:

- (void)setFoo:(int)newFoo
{
    _foo = newFoo;
}

如果没有这样的实现,就不会发生引用计数,因此分配的对象可能会过早地被释放或泄露。

答案 2 :(得分:1)

一个更重要的区别......

每当你使用self.prop KVC进场时,你可以观察到对象的变化,而_prop绕过它。