Objective-C in, out, inout, byref, byval,.. и так далее. Кто они такие?
Я обнаружил что-то незнакомое при чтении руководства 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
Единственное, что я знаю, это oneway
. Что другие?
Ответы
Ответ 1
Это аннотации параметров метода и возвращаемых значений, которые использовались Distributed Objects. Я говорю, потому что, по-видимому, они больше не подписывают их в документации на Яблоки. Раньше был раздел "Удаленные сообщения" в документе "Язык программирования Objective-C", на который по-прежнему ссылается документ "Распространенные объекты".
- in: аргумент является только входным аргументом и не будет упоминаться позже
- out: аргумент - это только выходной аргумент, используемый для возврата значения по ссылке
- inout: - аргумент ввода и вывода
- const: аргумент (указатель) постоянный
- bycopy: вместо прокси /
NSDistantObject
, передать или вернуть копию объекта
- byref: использовать прокси-объект (по умолчанию)
Ответ 2
Помимо распределенных объектов, одна из этих аннотаций, по-видимому, используется ARC. Я наткнулся на следующее описание cla переход к выходному параметру путем обратной записи:
Если параметр не является параметром метода Objective-C, помеченным out
, тогда читается *p
, а результат записывается во временную примитивную семантику.
Это связано с такими методами, как - (BOOL)executeWithError:(out NSError **)error
.
Игнорируя ключевое слово out
, ARC имеет корректное поведение обработки объекта-ссылки, проходящего как __autoreleasing
, поэтому ARC обрабатывает параметр error
как имеющий тип NSError * __autoreleasing *
. Если вы используете переменную, отличную от другой, ARC добавит временную передачу переменной autoreleasing в функцию (для согласованности):
Исходный код
NSError *error;
[obj executeWithError:&error];
Pseudotransformed code
NSError * __strong error;
NSError * __autoreleasing temp;
temp = error;
[obj executeWithError:&temp];
error = temp;
С приведенным выше кодом строка temp = error
не понадобилась бы, если бы мы как-то знали, что temp
никогда не будет считаться. Здесь вступает в действие аннотация out
. В цитированном описании, если out
отсутствует, компилятор должен добавить строку temp = error
, но если он содержит out
, он может исключить строку и сделать код немного меньше/быстрее. С out
преобразованный код становится:
NSError * __strong error;
NSError * __autoreleasing temp;
[obj executeWithError:&temp];
error = temp;
Конечно, если вы беспокоитесь о двоичном размере и скорости, вы должны просто закодировать следующее:
NSError * __autoreleasing error;
[obj executeWithError:&error];
Вполне возможно, что эти аннотации используются в других местах во всем компиляторе и во время выполнения и могут использоваться в будущем в других местах. Лично мне нравится использовать out
как подсказку для других разработчиков, что я не буду читать значение.
Ответ 3
Если кто-нибудь наткнулся на этот пост и имеет ту же путаницу, что и я, аргумент "in" также может быть ключевым словом, которое представляет собой быстрое перечисление. Подробнее см. здесь.
Ответ 4
Вы можете прочитать источники Objective-C http://www.opensource.apple.com/source/objc4/objc4-437.1/, чтобы понять, что означают эти аннотации.