【问题标题】:method taking mutli arguments in dot notation以点表示法采用多参数的方法
【发布时间】:2011-01-14 01:32:52
【问题描述】:

我在目标 c 上观看此视频。这家伙展示了一个带有多个参数的方法,它看起来像这样

- (void) setTo: (int) n over: (int) d
{ .... }

他展示了使用它:

[myFraction setTo: 100 over:200];

括号表示法在点表示法中的外观如何?我不明白那是什么 意思是,有人知道吗?谢谢

【问题讨论】:

    标签: objective-c


    【解决方案1】:
    [myFraction numerator]
    

    可以写成

    myFraction.numerator
    

    但您也可以分配诸如

    之类的值
    instance.property = value
    

    但您不能以点表示法传递多个参数。

    【讨论】:

      【解决方案2】:

      在Objective-C中,我们可以在中间中为方法命名。因此,当他写[myFraction setTo:100 over:200]; 时,over 可能意味着……好吧,无论他想要什么。这是他选择的方法名称的一部分。在这种情况下,他可能试图让这种方法听起来像英语。 (“将此分数设置为 100 超过 200。”我们在正常语音中经常将分数读作“分子超过分母”。)

      我们经常编写一些称为“访问器”的方法:这些是- (int)variable(称为“getters”)和- (void)setVariable:(int)newValue(称为“setters”)形式的方法。我这里的示例假定分别返回或更改名为variable 的实例变量。以下是方法实现的样子:

      - (int)variable
      {
          return variable;
      }
      
      - (void)setVariable:(int)newValue
      {
          variable = newValue;
      }
      

      对于你的类的几乎每个实例变量都有这样的访问器是很常见的。在某些时候,有人厌倦了写 [myInstance setVariable:20]; 之类的东西,并决定他们宁愿它看起来像许多其他语言一样,myInstance.variable = 20;

      因此,Objective-C 2.0 添加了点表示法,它允许您编写...

      myInstance.variable,在大多数情况下完全等同于[myInstance variable](并且不直接访问实例变量variable!),并且...

      特例myInstance.variable = 20;,完全等价于[myInstance setVariable:20];。再次注意,这不会直接访问variable,它会向myInstance 发送消息。因此,如果我们在 setVariable 中编写了一些其他代码,如果我们使用点符号,它仍然可以访问。

      点表示法设计用于访问器。理论上,您也可以将它用于任何返回值且不带参数的方法(例如myArray.count)。将它用于其他任何事情 (myInstance.doSomeAction) 的风格非常很差。不要这样做。因此,我相信您现在可以猜到,[myFraction setTo:100 over:200] 没有等效的点表示法,因为它需要 2 个参数,并且不是访问器。

      【讨论】:

      • 我来自 php 背景,过去我学过许多其他语言。当我查看目标 c 中的方法时,我会将其与 php 中的函数或我从过去学习 c 方式中回忆的任何内容进行比较。这个 - (void) setTo: (int) n over: (int) d 如何在像 c 这样的语言中进行比较? void function setTo(int n,int d) { } where do over: come in??
      • over: 是方法名称的一部分。 setTo(int n, int d) 不是一个很好的类似 C 函数。 setTo_over_(int n, int d) 更好。有问题的方法的全名不是setTo,而是setTo:over:。参数恰好在方法的中间。
      【解决方案3】:

      点表示法是仅用于属性访问的简写表示法。编译器将其转换为适当的 setter/getter 方法调用。它只是语法糖。

      所以给定这个属性访问使用点符号:

      myFraction.numerator=100;
      

      编译器将其替换为以下等效代码:

      [myFraction setNumerator:100]
      

      现在应该清楚为什么不能使用点表示法向对象发送普通消息了。我什至想不出它应该是什么样子。

      关于点与括号符号的讨论很多。反对点符号的论据之一是它特别是对初学者产生的混淆。其他语言当然也使用属性访问器的方法,但是它们比 Objective-C 更一致地隐藏了这一事实。

      【讨论】:

      • 我不确定您是指@property 意义上的“属性”,还是更一般的意义上的“属性”,但请注意,点表示法与手写访问器配合得很好(即使@ 987654324@ 从未在 .h) 中声明。如果你愿意的话,我什至会说,对myArray.count 之类的东西使用点符号并不是一种糟糕的风格。
      【解决方案4】:

      不能使用点符号传递多个参数。可通过点表示法使用的 setter 必须具有原型

      -(void)setXxxx:(type)value;
      

      但是,您可以创建一个辅助结构来将所有参数组合为一个:

      struct Fraction { int n, d; };
      struct Fraction MakeFraction(int n, int d) {
         struct Fraction r;
         r.n = n;
         r.d = d;
         return r;
      }
      ...
      -(void)setValue:(struct Fraction)f { ... }
      ...
      myFraction.value = MakeFraction(100, 200);
      

      (和 a “超过”b 表示 a / b。)

      【讨论】:

        【解决方案5】:

        从外观上看,这个方法是设置对象的两个实例变量/属性,分子(n)和分母(d)。除非你将它分成两个调用,否则你不能使用点符号来做到这一点:

        myFraction.numerator=100;
        myFraction.denominator=200;
        

        请注意,点表示法仅用于访问实例变量/属性,不能替代消息发送。

        【讨论】:

        • 这是错误的!首先,点符号不访问实例变量,其次,它等同于消息发送:myFraction.numerator = 100[myFraction setNumerator:100] 完全相同。
        • 点语法仅用于访问器方法,它们是访问实例变量/属性的方式。不推荐任何其他用途(尽管有可能:请参阅 Apple 的“Objective-C 编程语言”中“点语法”下的“不正确使用”部分。也许我的原始答案不够清楚,但我是不完全,我想你可以用更礼貌的语气...
        猜你喜欢
        • 1970-01-01
        • 2011-11-24
        • 1970-01-01
        • 1970-01-01
        • 2012-09-21
        • 2018-06-21
        • 2020-06-30
        • 2012-07-08
        • 1970-01-01
        相关资源
        最近更新 更多