Используйте расширение класса для выборочной видимости в Objective-C

Имеет ли смысл помещать расширения классов в их собственные .h файлы и #import их выборочно, чтобы получить различные уровни видимости для методов и свойств класса? Если это плохая идея (или не сработает), почему?


person Dan Rosenstark    schedule 18.08.2011    source источник


Ответы (2)


Это отличная идея и именно поэтому были разработаны расширения классов (и почему они отличаются от категорий).

А именно:

Foo.h

@interface Foo:NSObject
...public API here...
@property(readonly, copy) NSString *name;
@end

Foo_FrameworkOnly.h

@interface Foo()
@property(readwrite, copy) NSString *name;
@end

Foo.m

#import "Foo.h"
#import "Foo_FrameworkOnly.h"

@interface Foo()
... truly implementation private gunk, including properties go here ...
@end

@implementation Foo
@synthesize name = name_;
@end

И эффективно иметь свойство, открытое только для чтения и частное чтение и запись только для файлов реализации, которые импортируют Foo_FrameworkOnly.h.

person bbum    schedule 18.08.2011
comment
Спасибо @bbum, это здорово ... ваш пример дает вам общедоступный, пакетный (или что-то еще) и частный, что почти все, на что я когда-либо надеялся. Лично я считаю ужасным делать это на уровне файлов, но я полагаю, что это цена того, чтобы быть так близко к металлу. - person Dan Rosenstark; 18.08.2011
comment
Существует огромная сложность, связанная с поддержкой частного API на уровне, отличном от уровня файла, и, особенно в чисто динамическом языке, таком как Objective-C, частный в любом случае фактически бессмысленен (т. Е. Компилятор не может скомпилировать или полностью скрыть частные символы ). - person bbum; 18.08.2011
comment
(Я не возражаю - просто говорю, что это значительная стоимость). Это тоже может показаться вам интересным: stackoverflow.com/questions/2158660/ - person bbum; 18.08.2011
comment
вы имеете в виду огромную сложность для среды выполнения (и, возможно, компилятора). Спасибо за ссылку, она помогает конкретизировать обсуждение. - person Dan Rosenstark; 19.08.2011
comment
Ага; и время выполнения, и компилятор, безусловно. - person bbum; 19.08.2011
comment
Я хотел сказать, что у нас сложность для среднего разработчика вместо сложности во времени выполнения и компилятора. Мне не хватает ключевых слов для видимости в C #, Java и даже ActionScript. Но я отвлекся. - person Dan Rosenstark; 19.08.2011
comment
Этот пример чрезвычайно полезен для разработчиков фреймворка, которые хотят иметь более детальный контроль над видимостью интерфейса класса. - person shilgapira; 02.07.2012

Расширение класса (в отличие от подкласса) в Objective-C осуществляется с помощью категорий. В Xcode перейдите в меню «Файл»> «Создать»> «Файл» и выберите «Категория Objective-C». Он спросит, как назвать категорию и к какому классу она должна расширяться. Вы получите пару .h / .m, в которую поместите свой интерфейс и реализацию соответственно. Если вам нужен доступ к функциям, предоставляемым в вашем расширении, просто импортируйте его файл .h.

person adamrothman    schedule 18.08.2011
comment
Категории и расширения похожи , но они не совпадают. Расширения классов похожи на анонимные категории, за исключением того, что объявляемые ими методы должны быть реализованы в основном блоке @implementation для соответствующего класса. - person albertamg; 18.08.2011
comment
@albertamg, теоретически, если .m не импортирует .h, содержащий расширение класса, тогда ему не нужно его реализовывать, верно? - person Dan Rosenstark; 18.08.2011
comment
@Yar Ну, компилятор не будет жаловаться на неполную реализацию, если расширение класса не импортировано в файл .m. - person albertamg; 18.08.2011
comment
Голос против был моим; расширения классов не являются категориями и наоборот. Это совершенно разные вещи (например, расширения не могут иметь реализации, категории не могут влиять на синтез свойств). И, да, если расширение не импортировано, компилятор не будет знать, что требуется реализация (категории также ведут себя по-разному; категории вообще не обязательно иметь соответствующую @implementation). - person bbum; 19.08.2011