Objective-C in,out,inout,byref,byval,..等等。 他们是什么?

在阅读@encoding Objective-C手册时,我发现了一些不熟悉的东西。

 Table 6-2 Objective-C method encodings Code Meaning r const n in N inout o out O bycopy R byref V oneway 

我唯一知道的是oneway 。 其他人是什么?

这些是由分布式对象使用的方法参数和返回值的注释。 我说因为苹果公司文件中显然没有迹象。 “Objective-C编程语言”文档中曾经有一个“远程消息传递”部分,该部分仍然被“分布式对象编程主题”文档引用。

  • in:参数只是一个input参数,稍后不会被引用
  • out:参数只是一个输出参数,用于通过引用返回一个值
  • inout:参数既是input参数又是输出参数
  • const:(指针)参数是常量
  • bycopy:不是使用代理/ NSDistantObject ,而是传递或返回对象的副本
  • byref:使用代理对象(默认)

除分布式对象之外,这些注释之一似乎被ARC使用。 在clang的描述中,我通过回写传递给出了一个参数 :

如果参数不是一个标出的Objective-C方法参数,则读取*p ,并将结果写入带有原语语义的临时文件中。

这与如下方法- (BOOL)executeWithError:(out NSError **)error

忽略out关键字,ARC有一个明确的行为,把被引用的对象作为__autoreleasing传递 ,所以ARC将error参数视为具有NSError * __autoreleasing *types。 如果使用其他限定的variables,ARC将在函数中添加一个临时自动释放variables传递(用于一致性):

原始代码

 NSError *error; [obj executeWithError:&error]; 

伪转换的代码

 NSError * __strong error; NSError * __autoreleasing temp; temp = error; [obj executeWithError:&temp]; error = temp; 

通过上面的代码,如果我们知道temp永远不会被读取,那么temp = error就不是必要的了。 这就是out注释的起源。 根据引用的描述,如果缺less编译器必须添加行temp = error但如果它包含它可以排除行,并使代码稍微更小/更快。 用转换后的代码变成:

 NSError * __strong error; NSError * __autoreleasing temp; [obj executeWithError:&temp]; error = temp; 

当然,如果你担心二进制大小和速度,你应该只是编码如下:

 NSError * __autoreleasing error; [obj executeWithError:&error]; 

这些注释完全可能在整个编译器和运行时间的其他地方使用,并可能在未来的更多地方使用。 就我个人而言,我喜欢用其他开发人员的提示来表明我不打算读取它的价值。

任何人都偶然发现了这个post,和我有同样的困惑,“in”参数也可以是一个代表快速枚举的关键字。 在这里看到更多的细节。