Objective-C in,out,inout,byref,byval, .. and so on. What are they?

Objective C

Objective C Problem Overview


I discovered something unfamiliar while reading Objective-C manual for @encoding.

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

The only thing I know is oneway. What are the others?

Objective C Solutions


Solution 1 - Objective C

Those are annotations for method parameters and return values which were used by Distributed Objects. I say were because apparently there’s no sign of them in Apple’s documentation any longer. There used to be a Remote Messaging section in The Objective-C Programming Language document, which is still referenced by the Distributed Objects Programming Topics document.

  • in: argument is an input argument only and won’t be referenced later
  • out: argument is an output argument only, used to return a value by reference
  • inout: argument is both an input and output argument
  • const: the (pointer) argument is constant
  • bycopy: instead of using a proxy/NSDistantObject, pass or return a copy of the object
  • byref: use a proxy object (default)

Solution 2 - Objective C

Beyond Distributed Objects, one of these annotations appears to be used by ARC. I came across the following in clang's description of passing to an out parameter by writeback:

> If the parameter is not an Objective-C method parameter marked out, then *p is read, and the result is written into the temporary with primitive semantics.

This has to do with methods like - (BOOL)executeWithError:(out NSError **)error.

Ignoring the out keyword, ARC has a well-defined behavior of treating by-reference object passing as __autoreleasing, so ARC treats the error parameter as having a type of NSError * __autoreleasing *. If you use an otherwise qualified variable, ARC will add a temporary autoreleasing variable pass into the function (for coherence):

Original code

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

Pseudotransformed code

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

With the above code, the line temp = error would be unnecessary if we could somehow know that temp will never be read. This is where the out annotation comes into play. Per the quoted description if out is missing the compiler must add the line temp = error but if it does contain out it can exclude the line and make the code just a little bit smaller/faster. With out the transformed code becomes:

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

Of course, if you're that worried about binary size and speed, you should just code the following:

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

It is entirely possible that these annotations are used other places throughout the compiler and runtime, and may be used in more places in the future. Personally, I like using out as a hint to other developers that I'm not going to read the value.

Solution 3 - Objective C

Incase anyone has stumbled across this post and has the same confusion as me, the 'in' argument can also be a keyword that represents fast enumeration. See here for more details.

Solution 4 - Objective C

You can read the Objective-C runtime sources http://www.opensource.apple.com/source/objc4/objc4-437.1/ to understand what these annotations mean.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioneonilView Question on Stackoverflow
Solution 1 - Objective Cuser557219View Answer on Stackoverflow
Solution 2 - Objective CBrian NickelView Answer on Stackoverflow
Solution 3 - Objective CGWedView Answer on Stackoverflow
Solution 4 - Objective CnstView Answer on Stackoverflow