Objective-C in,out,inout,byref,byval,..等等.这些是什么?

Eon*_*nil 63 objective-c

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

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

我唯一知道的是oneway.还有什么?

小智 84

这些是分布式对象使用的方法参数和返回值的注释.我说因为显然Apple的文档中没有任何迹象表明它们了.在Objective-C编程语言文档中曾经有一个远程消息传递部分,它仍然由分布式对象编程主题文档引用.

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

  • FWIW,Apple在新的`UIScrollViewDelegate`方法中使用`inout`.(`targetContentOffset :( inout CGPoint*)targetContentOffset`.无论如何,这就是我来到这里的方式. (51认同)
  • 其实我也是.如果他们可以使用inout,为什么他们需要做一些复杂的事情,比如做双指针来获取错误?实际上,鉴于他们传递CGPOINT*,他们根本不需要指定inout.这是一个指针.CGPOINT是一个结构.只要将新的CGPOINT放到targetContentOffset指向的地址,你就可以了. (6认同)

Bri*_*kel 23

超越分布式对象,其中一个注释似乎被ARC使用.我在clang的描述中通过回写传递给out参数时遇到了以下内容:

如果参数不是标记的Objective-C方法参数out,则*p读取,并将结果写入具有原始语义的临时参数.

这与像这样的方法有关- (BOOL)executeWithError:(out NSError **)error.

忽略out关键字,ARC有一个明确定义的行为,即将by-reference对象视为传递__autoreleasing,因此ARC将error参数视为具有类型NSError * __autoreleasing *.如果使用其他合格的变量,ARC将在函数中添加临时自动释放变量传递(用于一致性):

原始代码

NSError *error;
[obj executeWithError:&error];
Run Code Online (Sandbox Code Playgroud)

伪转换代码

NSError * __strong error;
NSError * __autoreleasing temp;
temp = error;
[obj executeWithError:&temp];
error = temp;
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,temp = error如果我们能够以某种方式知道temp将永远不会被读取,那么该行将是不必要的.这是out注释发挥作用的地方.根据引用的描述如果out缺少,编译器必须添加该行,temp = error但如果它确实包含out它,则可以排除该行并使代码稍微更小/更快.随着out转换后的代码变为:

NSError * __strong error;
NSError * __autoreleasing temp;
[obj executeWithError:&temp];
error = temp;
Run Code Online (Sandbox Code Playgroud)

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

NSError * __autoreleasing error;
[obj executeWithError:&error];
Run Code Online (Sandbox Code Playgroud)

这些注释完全可能在整个编译器和运行时的其他位置使用,并且可能在将来的更多地方使用.就个人而言,我喜欢使用它out作为其他开发人员的提示,我不打算读取它的价值.

  • @denis631 No.`(out NSError**)`与`(out NSError*__autoreleasing*)`相同``(NSError**)`与`(NSError*__autoreleasing*)`的类型相同.注入`__autoreleasing`是ARC设计的一部分,类似于所有变量都是`__strong`,除非指定.`out`不是类型的一部分,而是编译器可用于优化的注释. (2认同)