【问题标题】:Function call instead of self messaging — When to use what?函数调用而不是自我消息传递——何时使用什么?
【发布时间】:2011-06-07 08:37:02
【问题描述】:

在Objective-C中,当我想调用一个子程序时,我会向一个对象发送一条消息,例如:

[self mySubroutine:myParameter];

有一个(可以忽略不计?)性能损失,所以我可以只使用 C 风格的函数调用:

mySubroutine(myParameter);

后者的实现将驻留在类的 @implementation 上下文之外。

这是禁忌吗?这很常见吗?有这方面的最佳实践吗?

【问题讨论】:

  • 调用 C 函数而不是发送 Objective-C 消息只是为了性能是......叹息。你还不如干脆不使用 Objective-C!
  • 说,我有一个 sin_approx() 函数,它可以计算 sin() 的粗略估计——对于手头的目的来说已经足够了,但在性能方面比 sin() 更省力。 (例如,想想 iPhone 上的实时声音合成。)这更像是一种实用功能,而不是“向对象发送消息”。更重要的是,如果函数应该是可重用的并且不与类绑定,我无法想象创建一个数学实用程序类的单例对象,只是为了更快地做一些事情。
  • 函数确实是这样。
  • @BoltClock 相反,当函数和类之间没有有意义的关系时,使用Objective-C消息传递只是为了它,就像“......叹息”一样。
  • @walkytalky: -(void)agreeWith:(NSString *)user { NSLog(@"@%@: Totally.", user); } [self agreeWith:@"walkytalky"];

标签: objective-c c subroutine


【解决方案1】:

请注意,这些不一定是等效的。由于-mySubroutine 是一个实例方法,它可能需要访问给定的实例。在这种情况下,您的 mySubroutine() 函数也应该有另一个实例参数。

一般来说,使用一种方法。如果您担心性能,1您可以随时为方法获取 IMP 并将其用作函数,而不是标准的 Objective-C 消息调度基础架构。

也就是说,使用函数的一些缺点:

  • 它们不能被子类覆盖;
  • 没有自省(使用运行时获取由 Objective-C 类声明的方法列表时,不会枚举函数);
  • 它们不能用作声明属性的访问器/修改器;
  • Key-Value Coding 看不到它们;
  • 它们不能直接用于Objective-C消息转发;
  • 它们不能直接用于 Cocoa API 需要选择器的各种情况(例如,使用 NSTimer 时)。

使用函数的一些优点:

  • 它们不能被子类覆盖(如果您想防止这种情况);
  • 没有自省(如果您想阻止这种情况);
  • 它们可以内联;
  • 它们可以具有文件范围 (static),从而防止其他文件中的代码访问它们。

1当您确定消息调度基础设施实际上是一个瓶颈时。这确实发生了;例如,一些 Apple 音频示例不使用 Objective-C 进行音频处理。

编辑:根据 OP 的评论,函数的另一个优点是它们不一定与类相关。如果角度正弦的近似值的计算不依赖于 Objective-C 实例,则无需将其设为方法——函数更适合。

【讨论】:

  • 你能解释一下什么是对 KVC 和自省可见吗?
  • @Kris 我添加了一些关于自省的内容以及指向 Apple 的 KVC 文档的链接。
【解决方案2】:

在您拥有静态实用函数的地方可能值得使用,例如在数学库中。

一般来说,如果您需要作用于对象状态的方法,那么 C 方法不会有太大用处,因为您无法隐式访问 self,除非您将其显式传递为参数。

您也可能会遇到命名空间问题。使用 Objective-C 不同的类可以共享方法名称,使用 c 方法,您的所有函数都需要不同的签名。

我个人会一直使用objective-c方法,性能差异可以忽略不计。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2021-08-06
    相关资源
    最近更新 更多