【问题标题】:Whats the difference between setting a property in an object through dot notation vs setter?通过点符号与 setter 在对象中设置属性有什么区别?
【发布时间】:2016-04-09 23:59:57
【问题描述】:

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

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

A 类和 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 的情况下,它知道有一个类响应 setProperty1 方法,所以编译器允许它?如果是,看起来下面对 Q 的答案(这也是我最初的理解)是不正确的。即点符号不会被 setter 替换。

Difference between setting a property directly and using its setter?

【问题讨论】:

标签: objective-c inheritance setter


【解决方案1】:

问题是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:] 的另一种说法,所以不会因为你不能使用那个符号而丢失任何东西。

【讨论】:

  • 您的回答充分回答了为什么 Xcode 乐于在一种情况下而不是另一种情况下允许点表示法的问题,但可能值得一提的是,在这种情况下,实际的 差异 Xcode 对 dot notation is nothing 很满意。
  • @nhgrif 一个重要的区别。编译器需要静态类型来查找属性声明。在声明中,访问器名称可能被定义为非默认名称。在 Apple 的布尔属性框架中经常出现这种情况:@property (getter=isHidden) BOOL hidden;。在这种情况下,为receiver.hidden[receiver hidden] 发出的代码之间存在实际差异。我认为这就是编译器坚持使用点符号的静态类型的原因。
猜你喜欢
  • 2011-06-25
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2016-07-27
  • 1970-01-01
  • 2021-08-01
  • 2017-03-27
  • 2020-12-15
相关资源
最近更新 更多