Пример использования `oneway void` в Objective-C?

Я нашел странное ключевое слово в NSObject.h

- (oneway void)release;

Я искал в Интернете и узнал, что это связано с асинхронной передачей сообщений, которая похожа на передачу сообщений Erlang.

Кажется, это может сделать много интересного. Каковы некоторые примеры использования этого ключевого слова?

Ответ 1

oneway используется с API-интерфейсом распределенных объектов, который позволяет использовать объекты objective-c между различными потоками или приложениями. Он сообщает системе, что он не должен блокировать вызывающий поток до тех пор, пока метод не вернется. Без него вызывающий блок будет блокироваться, хотя тип возвращаемого метода недействителен. Очевидно, что он никогда не используется ни с чем другим, кроме void, так как это означает, что метод возвращает что-то, но вызывающий не получает его.

Подробнее о распределенных объектах см. Cocoa Концептуальные DistrObjects.

Ответ 2

Также представляется необходимым устранить предупреждение с XCode 4.2 (LLVM). В частности:

-(void) release { }

дает следующее предупреждение в XCode 4.2 (с LLVM):

warning: Semantic Issue: конфликтующие модификаторы распределенных объектов по типу возврата в реализации 'release'

Предупреждение можно устранить, добавив модификатор oneway:

-(oneway void) release { }

Это в реализации синглтона, поэтому релиз действительно ничего не делает.

Это необходимо (по крайней мере, для устранения предупреждения) на iOS, а также на OS X. Протокол NSObject в документах iOS определяет release как (oneway void), хотя в iOS нет распределенных объектов. Похоже, LLVM выбирает это, тогда как GCC не делает.

Ответ 3

Согласно документации Apple, oneway используется только для распределенного объекта (а не для многопоточности).

Модификатор oneway используется, только если объект удален. В этом случае вызов release может возвращаться асинхронно (до того, как метод завершится). В сети это имеет смысл, потому что ожидание сообщения возврата может занять некоторое время.

Метод release не имеет возвращаемого значения, поэтому вызов можно выполнить асинхронно. Напротив, сохранение и автозагрузка возвращают идентификатор, поэтому нам нужно ждать, пока сообщение о возврате будет передано по всей сети.