Сравнение различных способов привлечения частных членов в Objective C

Я пришел из мира С++/Java, где совершенно очевидно, как создавать частных членов. Тем не менее, я видел несколько способов сделать это в Objective C, и я хотел бы услышать минусы и плюсы.

1) Объявите их как @private в файле .h

@interface MyClass : NSObject
{
    @private
    int someMember;  
}
@end

2) Объявите их в интерфейсе внутри файлов .m

@interface MyClass() {
    int someMember;  
}
@end

@implementation MyClass
@end

3) Объявите их в реализации

@implementation MyClass {
     int someMember;  
}
@end 

Каков предпочтительный метод и почему? Я пропустил другие методы?

Ответ 1

Мои предпочтения: # 3:

// MyClass.m
...
@implementation MyClass {
     int someMember;
}
@end

Это позволяет вам четко абстрагироваться и минимизировать зависимости.

Так как каждый объект objc распределяется динамически и физическая зависимость минимальна, вы можете иметь самое быстрое время сборки и наименьшее количество ресурсов для представления самого богатого объекта (например, минимальный #import и физическая зависимость).

Абстракция также является огромным плюсом - частный является дефолтом, и нет причин, по которым вы должны отклоняться от этого, и мало оснований подвергать внутренности другим. Это скрывает все это очень хорошо, при этом безопасность типа не скомпрометирована. Большой плюс: вы также можете легко объявлять значения С++ в своем объекте, не подвергая всех всем зависимостям библиотек С++, а не PIMPL, а не структуре в глобальной области, а не void **, но правильному значению. это отличный компиляционный брандмауэр. Если вы работали над большими проектами C или С++, вы можете радоваться.

Конечно, объявление ivars, как показано в опции № 2, все это. Так что это в значительной степени зависит от того, где и как вы предпочитаете видеть переменные. Декларация ivar является конкретной, тогда как свойство может быть абстрагировано - поэтому я предпочитаю группировать бетон с бетоном и интерфейс с интерфейсом, но в любом случае; # 2 или # 3 идеальны, если вам не нужна обратная совместимость.

Если вы хотите (псевдо) частные свойства, я рекомендую вам объявить их в продолжении класса:

// MyClass.m
...
@interface MONClass ()
@property (nonatomic, copy) NSString * string;
@end

Ответ 2

Вы удобно перечислили их почти в хронологическом порядке добавления к Objective-C.

Я думаю, что это в значительной степени вопрос стиля, но я бы сказал, что 99% времени:

(1) не помещают их в файл .h, потому что файл .h является фактически опубликованным интерфейсом, и нет причин публиковать подробности реализации;

(2) помещают их в @implementation, а не в расширение класса @interface, чтобы избежать постороннего синтаксиса. У вас всегда будет реализация, у вас может не быть расширения класса.

Ответ 3

Если кто-то хочет использовать MyClass без его редактирования, они быстро прочитают заголовочный файл, чтобы выяснить, как он работает. Поскольку они не заботятся о ваших личных переменных, лучше оставить их вне заголовка.

Если вам нужны частные свойства или приватно реализованный протокол, вам нужно использовать продолжение класса в файле .m.

@interface MyClass () <SomeKindOfDelegate>
@property id someProperty;
@end

@implementation MyClass
@synthesize someProperty;
- (void)someKindOfDelegateMessage:(id)sender { }
@end

К тому времени, как вы это сделали, вы также можете поместить ваши переменные-члены в продолжение.

@interface MyClass () <SomeKindOfDelegate>
{
    int someMember;
}
@property id someProperty;
@end

@implementation MyClass
@synthesize someProperty;
- (void)someKindOfDelegateMessage:(id)sender { }
@end