1

可能重复:
self.ivar 和 ivar 之间的区别?

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

当你有一个带有变量的类时

@property (nonatomic) NSInteger num;

你想改变变量,通常你可以做

[self setNum: newNum]

但你也可以

num = newNum

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

[sample setNum: newNum]

但是,如果您要更改类中的变量,那么任何一种方式都可以吗?

4

3 回答 3

2

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

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

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

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

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

//.h
@interface CFExampleStack : NSObject 

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

@end

//.m
@interface CFExampleStack ()

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

@end
于 2012-12-25T04:38:50.490 回答
1

仅仅是因为可以在自己的类之外调用带有 setter 的第二种方法吗?

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

obj->publicIvar = 42;

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

此外,如果您使用自定义 setter 方法,那么您有机会在更新实例的属性时执行自定义操作。例如,如果更改backgroundColora 的属性,UIView除了将新对象分配给其适当的 ivar 之外,它还需要重绘自身,UIColor为此,需要具有副作用的自定义 setter 实现。

此外,在保存对象的实例变量的情况下,还有保留(“强”)和复制的属性。为诸如整数之类的原始类型编写 setter 非常简单

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

然后,相比之下,保留或复制的属性需要适当的内存管理调用:

- (void)setBar:(Bar *)newBar
{
    if (_bar != newBar) {
        [_bar release];
        _bar = [newBar retain]; // or copy
    }
}

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

于 2012-12-25T04:37:51.487 回答
1

还有一个重要的区别...

每当你使用self.propKVC 时,你可以观察到对象的变化,同时_prop绕过它。

于 2012-12-25T06:30:20.547 回答