Статические методы без сохранения состояния и функции C в Objective-C - PullRequest
5 голосов
/ 21 ноября 2011

С точки зрения хорошей практики кодирования в Objective-C, если я создаю функцию, у которой нет состояния, лучше написать ее как статический метод некоторого класса или как функцию C?

Например,У меня есть специальный метод поиска filepath, который проверяет каталог Caches перед тем, как перейти к основному NSBundle.В настоящее время я использую его как статический метод в другом пустом классе Utils.Должна ли это быть функция C вместо этого?

Причина, по которой я решил использовать статический метод (на данный момент), заключается в том, что a) он соответствует синтаксису Objective-C и b) класс помогает классифицироватьметод.Однако я чувствую, что немного изменяю, так как я мог легко заполнить свой класс Util этими статическими методами без состояния и в итоге получить уродливый «класс оболочки», единственной целью которого было бы их удержание.

Какую конвенцию вы используете?Является ли одно «лучше» другого по какой-то объективной метрике?Спасибо!

Ответы [ 3 ]

2 голосов
/ 21 ноября 2011

Если вы можете подумать о существующем классе , из которого этот метод может стать хорошим методом, вы можете добавить в него свой метод, создав категорию Objective-C. Это сохраняет ваши две причины для использования статического метода, не загрязняя пространство классов дополнительным классом.

Например:

@interface NSString (MyStringCategories) 
- (NSString*) myCoolMethod;
@end

// [StringCategories.m]
#import "StringCategories.h"

@implementation NSString (MyStringCategories)
- (NSString*) myCoolMethod {
    // do cool stuff here
    return whateverYouLike;
}
@end

Теперь вы можете отправить myCoolMethod на любую строку. Круто!

В вашем конкретном случае, похоже, что метод в NSBundle может быть подходящей архитектурой. И не забывайте, что это может быть метод класса, поэтому вам не нужно ничего создавать для вызова вашего метода.

1 голос
/ 21 ноября 2011

Если нет класса, с которым можно было бы четко связать его, я использую функцию. Я также использую функции для этих служебных битов, потому что они могут быть удалены, если они не используются или на них нет ссылок. В связи с этим также полезно использовать функцию, потому что ошибка ссылки лучше, чем ошибка времени выполнения (даже .m был случайно исключен из сборки или если на него ссылалась другая внешне обновленная методика). Одна проблема с символами ObjC состоит в том, что они не удаляются, поэтому они, естественно, несут большую степень зависимости - все методы и классы objc, а также необходимые методы категорий должны существовать в конечном двоичном файле. Это не проблема для действительно небольших программ или библиотек, но она быстро набирает вес со средними / большими системами и библиотеками.

Все не нужно объявлять в @interface - особенно в больших системах, где все эти объявления действительно превратят ваши взаимозависимости в спагетти. По сравнению с методами, функции быстрее, меньше, могут лучше оптимизироваться компилятором или во время компоновки и могут быть удалены, если на них нет ссылок.

Если вам нужен полиморфизм, он просто принадлежит классу для организации или удобства, тогда метод класса или экземпляра часто является лучшим выбором.

Я также минимизирую методы объявления категорий по тем же причинам. Когда вы используете функции, вы можете легко написать метод-обертку там, где он вам нужен, и получить лучшее из обоих миров.

1 голос
/ 21 ноября 2011

Это довольно сложный вопрос, потому что ответ для многих людей будет зависеть от их личных предпочтений и вкусов. Я лично думаю, что если у вас есть функция, которая является функцией, то есть она не имеет ничего общего с объектом, у нее нет внутреннего состояния и т. Д. Пожалуйста, позвольте ей быть функцией и не пытайтесь обернуть все, что вы можете в объект только потому, что вы используете язык ОО, и вы можете.

Чтобы мой ответ был коротким, позвольте мне обратиться к (imo) довольно хорошей книге:

http://www.gotw.ca/publications/c++cs.htm

Я знаю, что это для C ++, но есть немало идей, которыми можно поделиться с другими языками (особенно Objective-C и Objective-C ++), особенно из части, называемой «Разработка классов и наследование». Там вы найдете пункт с заголовком «Предпочитайте писать функции, не являющиеся членами группы».

Итог: «Функции, не являющиеся членами, не являющимися членами улучшают инкапсуляцию путем минимизации зависимостей [...] Они также разбивают монолитные классы [...] [и] улучшают универсальность [...]".

Я думаю, что в этом пункте есть доля правды.

...