Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cocoa Tips & Tricks

Cocoa Tips & Tricks

Vladimir Pouzanov

December 11, 2010
Tweet

More Decks by Vladimir Pouzanov

Other Decks in Programming

Transcript

  1. О чем мы сегодня поговорим ✤ Как правильно писать код

    в команде ✤ Для чего нужен VCS ✤ Советы по оформлению и типичные ошибки
  2. Как правильно писать код в команде ✤ Используйте эти правила,

    даже если вы пишите код сами ✤ и думаете, что исходники никто и никогда не увидит ✤ или это проект на 15 минут ✤ Представляйте граммар-наци с тесаком у себя за спиной
  3. Структура проекта ✤ Classes/ – отдельный каталог для классов ✤

    Tests/ – отдельный каталог для тестов ✤ xib’ы традиционно валяются в корне проекта ✤ *.png; *.jpg; etc. – выносить в Resources/ если их больше пяти штук ✤ В общем случае – выносить в отдельные каталоги логические группы файлов, когда их нагромождение в корне затрудняет поиск
  4. Структура проекта ✤ Tests – отдельная группа для Unit-тестов ✤

    Classes/ ✤ Support/ – код поддержки (дополнительные категории, общие делегаты) ✤ Controllers/, UI Controllers/ – контроллеры хранилища, сети, интерфейса. Удобно далее группировать по UITabBar’у ✤ Model/ – любые ORM-like классы, в том числе производные от NSManagedObject ✤ Other Sources/ – удачное место для всех «внешних» фреймворков (DDXML, Three20, ...)
  5. Названия файлов ✤ Отдельный хедер – изолированный класс или протокол:

    ✤ FooAppDelegate: FooAppDelegate.h ✤ Общий хедер – связанные классы и протоколы: ✤ FooController, FooControllerDelegate: FooController.h ✤ в том числе – связанные структуры данных (enum, struct) ✤ Отдельный хедер – категория: ✤ NSString (SmsLength): NSString+SmsLength.h (или NSStringAdditions.h) ✤ Нет хедера – Unit-тест: ✤ FooControllerTest: FooControllerTest.m
  6. Форматирование кода ✤ У проекта может быть только один стиль

    форматирования ✤ Это очень важно! ✤ Его любыми способами навязывает тимлид ✤ в том числе – хуки на VCS, финансовые штрафы ✤ если я ставлю { ... } в стиле “linux kernel”, то все мои девелоперы тоже ставят { ... } аналогично ✤ brew install uncrustify + UniversalIndentGUI
  7. Для чего нужен VCS ✤ VCS – Version Control System

    ✤ Средство для работы с версионным кодом, а не механизм для обмена файлами !=
  8. Для чего используют VCS ✤ «Закоммить что вчера делал» ✤

    «Давайте пока SDK4.0 в отдельный бранч засунем, потом разберемся» ✤ «Ты на этой неделе мало наработал»
  9. Для чего можно использовать VCS ✤ branch – средство активной

    паралельной разработки ✤ blame – механизм поиска авторства строк кода ✤ bisect (git) – оптимальный механизм поиска регрессионной ревизии ✤ log/diff – актуальная история изменений ✤ externals/submodules – разделение кода на подпроекты
  10. Use Git, Luke! ✤ Локальная история и bisect – два

    огромных плюса ✤ быстро работающие log, diff, blame ✤ Дешевые бранчи позволяют перестроить подход к написанию кода и систематизировать коммиты (см. bit.ly/git-branching) ✤ git-svn позволяет прозрачно и удобно работать в корпоративной «svn- среде»
  11. Общие принципы именования ✤ Ясность ✤ Краткие и ясные называния.

    Или хотя бы ясные ✤ insertObject: atIndex: – коротко и понятно ✤ insert: at: – что мы встявляем? Что означает второй аргумент? ✤ removeObjectAtIndex:, removeObject: – удачные названия ✤ remove: – что мы удаляем? ✤ Не придумывайте лишних аббревиатур ✤ destinationSelection:, setBackgroundColor: – хорошо ✤ destSel:, setBkgdColor: – плохо ✤ Для списка общеупотребляемых аббревиатур смотрите Coding Guidelines ✤ Соблюдайте ясность интерпретации названия ✤ sendPort – отправляет порт или возвращает порт отправки? ✤ displayName – показывает имя или возвращает значение заголовка?
  12. Общие принципы именования ✤ Постоянство ✤ Используйте имена, аналогичные применяемым

    в Cocoa/Cocoa Touch ✤ Особенно это важно для полиморфизма ✤ - (int)tag существует в ряде разных классов Cocoa (не связанных прямым наследованием) ✤ Не ссылайтесь на себя ✤ Имена не должны ссылатся на сам объект: ✤ NSString vs NSStringObject ✤ Исключение из правила – константы-маски и константы уведомлений: ✤ NSUnderlineByWordMask ✤ NSTableViewColumnDidMoveNotification
  13. Префиксы ✤ В Objective-C нет стандартных средств для реализации пространств

    имен ✤ Используйте префиксы в именах классов, протоколов, функций, констант и структур ✤ Используйте префиксы в названиях методов категорий, расширяющих стандартные классы ✤ Не используйте префиксы для других методов, имен полей
  14. Общие принципы именования ✤ Используйте «camel case» для названий классов

    и методов, состоящих из нескольких слов: ✤ fileExistsAtPath:isDirectory: ✤ Кроме общеупотребляемых аббревиатур: ✤ TIFFRepresentation
  15. Использование символа «_» ✤ Apple резервирует названия, начинающиеся на «_»

    для себя ✤ Это не значит, что вы никогда не столкнетесь с коллизией имени без префикса «_» при сабклассинге ✤ Будьте бдительны!
  16. Названия классов и протоколов ✤ Имя класса должно содержать существительное,

    которое описывает задачи класса ✤ Название класса должно начинаться с большой буквы ✤ Название протокола обычно обозначает общее поведение методов протокола, Apple рекомендует использовать герундий: ✤ NSLocking vs. NSLock
  17. Названия методов ✤ Названия начинаются с маленькой буквы ✤ Ключевые

    слова init, copy, new обозначают специальное поведение метода (retain count +1) ✤ Методы, которые описывают действие, выполняемое над объектом, удобно называть с глагола: ✤ - (void)invokeWithTarget:(id)target; ✤ - (void)selectTabViewItem:(NSTabViewItem *)tabViewItem;
  18. Названия методов ✤ Если метод возвращает значение аттрибута (getter), не

    используйте «get» в качестве префикса ✤ - (NSSize)cellSize; ✤ - (NSSize)calcCellSize; ✤ - (NSSize)getCellSize; ✤ «get» используется для индикации непрямой передачи результата ✤ - (void)getBytes:(void *)buffer length:(NSUInteger)length;
  19. Названия методов ✤ Не используйте анонимные аргументы, по названию метода

    должно быть понятно, как его использовать: ✤ - (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells: (BOOL)flag; ✤ - (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; ✤ Слово перед аргументом должно описывать аргумент: ✤ - (id)viewWithTag:(int)aTag; ✤ - (id)taggedView:(int)aTag;
  20. Названия методов ✤ Не используйте «and» для объединения частей имени

    метода ✤ - (int)runModalForDirectory:(NSString *)path andFile:(NSString *) name andTypes:(NSArray *)fileTypes; ✤ Кроме того случая, если «and» используется для объединения двух разных действий: ✤ - (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
  21. Свойства ✤ Используйте генерируемые свойства (@property) везде, где только возможно

    ✤ Свойства это: ✤ Ограничение доступа (readonly) ✤ Режим управления памятью (assign, retain, copy) ✤ Прозрачная реализация собственных методов доступа (getter, setter)
  22. Свойства ✤ Используйте nonatomic. Четко понимайте границы атомарности по умолчанию

    ✤ Используйте автоматически сгенерированные поля (@synthesize) ✤ В таком случае, блок { ... } в описании класса вообще можно опустить ✤ Для явного доступа к ivar (например в своем setter) используйте постфикс “_” (он некрасиво смотрится, что уменьшит желание его использовать): ✤ @property (nonatomic, copy) NSString *title; ✤ @synthesize title = title_; ✤ Никогда не используйте ivar_ нигде, кроме как в getter/setter
  23. «Приватные» методы и свойства ✤ Не выносите приватный код в

    общий хедер! ✤ Используйте или отдельный файл MyClass+Private.h, или просто анонимную категорию в начале MyClass.m: @interface MyClass () @property (nonatomic, readwrite, retain) *privateObjects; - (void)privateOperation; @end
  24. Используйте пулы памяти ✤ -autorelease – это дешево! ✤ Используйте

    рядом с new/init/copy/retain, чтобы не забыть потом сделать release ✤ Создавайте в своих классах воспомогательные конструкторы с автоматической делегацией объекта в ближайший пул: ✤ + (id)controllerWithSomeObject:(SomeObject *)object;
  25. Не забывайте про парные методы ✤ init – dealloc ✤

    viewDidLoad – viewDidUnload ✤ someProperty – setSomeProperty:
  26. Не надо визуального мусора ✤ Не проверяйте лишний раз объект

    на nil: ✤ if(myObj != nil) ✤ [myObj retain]; ✤ objc_msgSend делает это в любом случае
  27. Полезно почитать ✤ CocoaDevCentral – Cocoa Style for Objective-C ✤

    http://cocoadevcentral.com/articles/000082.php ✤ http://cocoadevcentral.com/articles/000083.php ✤ StackOverflow ✤ http://stackoverflow.com/questions/155964/what-are-best- practices-that-you-use-when-writing-objective-c-and-cocoa ✤ The Code Commandments: Best Practices for Objective-C Coding ✤ http://ironwolf.dangerousgames.com/blog/archives/913