通过点符号在对象中设置 属性 与 setter 有什么区别?

Whats the difference between setting a property in an object through dot notation vs setter?

看起来通过点符号设置 属性 与 setter 之间存在一些细微差别。

在我的 objective-C 代码中,我有一个 属性 可以设置为 class A 或 class B 的实例。所以我将其声明为@属性 id 委托

class A 和class B 具有相同的属性和方法。如果您在一个和另一个上调用 methodM1,只是实现(功能)不同。

我看到以下行不起作用(直接通过点符号使用 属性)

 self.delegate = [[Class A alloc] init];
 self.delegate.property1 = @"ABCD" ; //Does not work, get an error that property1 not defined on id

但是下一行有效

[self.delegate setPropert1:@"ABCD"] ; //works

有什么区别?是不是在 setter 的情况下,它知道有一个 class 响应 setProperty1 方法,所以编译器允许它?如果是的话,看来下面Q的答案(也是我原来的理解)不正确。即点符号不会被 setter.

取代

Difference between setting a property directly and using its setter?

问题是 self.delegate 被键入为 id。您可以向 id 发送任何消息,因此说

是合法的
[self.delegate setProperty1:@"ABCD"];

编译器会放开所有控制权,如果这条消息没有成功,你就可以让程序崩溃,因为这是一个 id.

但对于房地产,并没有这种放松的控制。要使用 属性,您必须具有定义了 属性 的实际类型。因此你可以说

((ClassA*)self.delegate).property1 = // ...

((ClassB*)self.delegate).property1 = // ...

但你不能说

self.delegate.property1 = // no, because self.delegate is an `id`

然而,这只是一个符号问题。即使你可以说 self.delegate.property1 这只是 [self.delegate setProperty1:] 的另一种说法,所以不会因为你不能使用该表示法而丢失任何内容。