【问题标题】:Objective-C: Getters should not be used for side effects compiler warningObjective-C:Getter 不应该用于副作用编译器警告
【发布时间】:2012-08-15 15:24:37
【问题描述】:

有人可以澄清这里发生了什么吗?我有一个名为:brainModel 的类,它又有一个名为:operandStack 的 NSArray。我只是在访问向它发送消息“removeAllObjects”的数组

self.brainModel.operandStack.removeAllObjects;

但是使用点表示法它会给我一个警告“未使用属性访问结果 - getter 不应该用于副作用”这到底是什么意思?

像这样使用嵌套括号语法不会给出警告:

 [[[self brainModel]operandStack]removeAllObjects];

顺便说一句,两者都有效...这与错误使用点表示法有什么关系吗?或者在像这样的消息传递对象时使用点表示法被认为是一种好习惯 - 向它发送诸如“removeAllObjects”之类的参数。

【问题讨论】:

  • 可能看到removeAllObjects 的返回类型为void,所以您显然没有将它用作吸气剂
  • @Paul.s 根本没有,很快就会看到我的答案。

标签: objective-c methods nsarray notation


【解决方案1】:

removeAllObjects 不是属性;这是一种方法。

使用属性访问表示法有效,因为通常使用同名方法访问属性。但是,预计获取属性的值不会更改包含该对象的对象(或进行任何其他更改),removeAllObjects 的情况并非如此。这些是编译器所指的“副作用”。

您可能希望改为执行此调用:

[self.brainModel.operandStack removeAllObjects];

这会获取selfbrainModel 属性,然后是self.brainModeloperandStack 属性,然后对其调用removeAllObjects

【讨论】:

    【解决方案2】:

    removeAllObjects 是一种方法。您不能通过点符号访问方法;只有属性。

    【讨论】:

    • 您可以,但您应该这样做吗?这是一个道德和宗教的问题。
    【解决方案3】:

    您不需要将每个方法都声明为属性——尤其是当它们正在修改对象时。 Getter 应该被视为属性的访问器(不直接暴露支持的 ivar)。也就是说,作为“动作”的方法将被声明为这样(即,在没有 @property 关键字的情况下声明并使用括号而不是点表示法调用)。

    【讨论】:

    • 这不能解释我的建议是怎么错的?我可以合法地声明一个带有返回值的方法并将其与点符号一起使用。在NSArray 中查看- (NSUInteger)count;,它没有被声明为@property (nonatomic, assign, readonly) NSUInteger count,但是很多人使用它没有任何问题。尽管您的回答解释了使用属性的哲学,但我认为它并不能解释编译器的抱怨。
    • @Paul.s 确实如此,只是您似乎不明白编译器抱怨的 这不是语法错误,这正是语法背后的哲学.
    • 同意重要的是哲学,但我只是说编译器必须处理具有void 返回的方法签名,否则它怎么知道它有副作用 -请记住,如果我的方法签名实际上返回了某些东西,我可以合法地添加副作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多