【问题标题】:Inline accessor (getter/setter) methods in Objective-CObjective-C 中的内联访问器(getter/setter)方法
【发布时间】:2016-01-22 02:08:21
【问题描述】:

数据封装,或者我喜欢称之为,谁拥有它,谁需要知道它,构成了很多面向对象的编程。需要知道的人通常会被访问器方法所满足,但是如果它们都导致 objc_msgsend 只是为了读取一个变量,那么这些方法就会变得非常昂贵。 C++ 用内联方法解决了这个问题——在定义之前使用“inline”关键字,或者在类声明中定义方法,编译器将访问器代码放在调用者的代码中,节省了与实际函数调用相关的开销。

class IntWrapper {
public:
   int getInt() { return anInt; }
protected:
   int anInt;
};

Objective-C 中的编译器错误会奖励类似的语法。在 Xcode 中搜索了语言指南(“[Object-Oriented] Programming with Objective-C”),我没有看到任何与方法的“内联”相关的参考。 Objective-C中是否有内联之类的东西?是不是叫别的东西?如果有人能指出我引用内联的文档,非常感谢。

使用简单的测试代码:

@interface ClassA : NSObject
{
   int anInt;
}
- (int) anInt;
@end

@implementation ClassA
- (int) anInt { return anInt; }
@end

查看使用它的代码的汇编,它看起来像大约 25 条指令。

【问题讨论】:

  • 只有 C 函数可以内联,不幸的是 Objective-C 方法不能。
  • 您可以在此处了解更多信息:stackoverflow.com/questions/8194504/…
  • 值得补充的是,约定是使用@property 来避免声明变量及其访问器的样板。

标签: objective-c inline accessor


【解决方案1】:

所有 Objective-C 方法都是动态调度的。它们可以被子类覆盖。它们甚至可以在运行时被 Objective-C 运行时 API 替换(“swizzled”)。

在某些方面,它们类似于 C++ 中的virtual 方法。

因此它们不能被内联。

顺便说一句,您引用的技术违反了您引用的原则(“谁拥有它,谁需要知道它?”)。将实现放在类声明中会将实现细节暴露给不需要知道它的客户。此外,将代码内联到客户端的编译器可以防止在没有重新编译的情况下更改实现,即fragile base class problem。现代 Objective-C 避免了脆弱的基类问题,这意味着框架类可以在不破坏客户端的情况下更改它拥有的实例变量。

【讨论】:

  • 还有,键值编码
  • 我认为 C++ 程序员必然会认为,如果你正在阅读接口,那么你只是在阅读 public: 部分中的方法和变量声明——而不是定义或其中的任何内容private:(显然,protected: 是否相关取决于您正在创作的课程)。我相当肯定我不会过时的说即使是私人存储也必须发布。这与 Objective-C 的思维方式相反,我们不能拥有任何真正私有的方法,而是根本不宣传它们。
  • ... 我猜有点像 Swift。虽然 Xcode 不会自动只显示界面部分。大概其他编辑会。我想我做了一个非常小的区别。当然,我已经给你投了赞成票。
  • @Tommy,确实 C++ 需要在类声明中声明实例变量。你可以使用pImpl 来缓解它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多