[Перевод] Минимализм Objective-C
Я часто пишу небольшие тестовые проекты на Objective-C, чтобы поэкспериментировать или поиграться с чем-нибудь. Обычно, я помещаю код в main.m и избавляюсь от всего остального: #!/usr/bin/env objc-run @import Foundation;
@implementation Hello: NSObject — (void) sayHelloTo: name { printf («Hello %s, my address is %p\n», [name UTF8String], self); } @end
int main () { id hello = [Hello new]; [hello sayHelloTo:@«sunshine»]; } Это полноценный проект из одного файла, готовый к выполнению. Под катом — описание приемов, позволивших прийти к данному минимализму.
Все пишется в main.m. Или «Test.m», или что угодно. Функция main () может находиться в любом файле. Используем objc-run. Если вы еще не сталкивались с ней, objc-run — прекрасная утилита, которая «позволяет легко использовать файлы Objective-C в качестве консольных скрипто-подобных задач». Установите ее: brew install objc-run и добавьте права на выполнение вашему исходному файлу: chmod u+x main.m Модули вместо предкомпиленных заголовков. Возможно, есть смысл в #imports и PCH в больших проектах, но для маленьких тестовых программ? Нет уж. Никаких объявлений @interface Я случайно узнал, что ObjC позволяет указывать суперкласс прямо в директиве @implementation. Не совсем понятно, с какой целью это допущено, но это позволяет полностью избавиться от блока @interface. Неявные типы параметров функций. Возвращаемые типы и параметры методов ObjC неявно равны (id), что значит-(id)doSomethingWith:(id)param; это абсолютно то же самое, что и -doSomethingWith: param;, но второй вариант выглядит удобнее. Никаких аргументов в main (). Хотя это считается плохой практикой, вполне допустимо писать void main () вместо int main (int argc, char**argv). Зачем это все объявлять, если вы все равно не пользуетесь этими аргументами? Избавляемся от return в main (). Начиная со стандарта C99, при возвращении управления от main () без оператора возврата — считается, что было вызвано return 0; printf вместо NSLog. NSLog — для сообщений об ошибках, а не для вывода текста — мне не нужно выводить путь к выполняемому файлу и ID потока на каждой строчке. Примечание переводчика: при отсутствии @interface меня раздражает вывод warning:
/dev/fd/63:3:17: warning: cannot find interface declaration for 'Hello' @implementation Hello: NSObject ^ 1 warning generated. Это warn_undef_interface, для которого нет соответствующего флага -W (для заглушения предупреждений по типам). Так что для себя я оставил пустой интерфейс. #!/usr/bin/env objc-run @import Foundation;
@interface Hello: NSObject @end
@implementation Hello — (void) sayHelloTo: name { printf («Hello %s, my address is %p\n», [name UTF8String], self); } @end
int main () { id hello = [Hello new]; [hello sayHelloTo:@«sunshine»]; }