Я должен выставить частную собственность подклассам. Поскольку в objc AFAIK нет такой вещи, как «защищенные свойства», я использую директиву @protected, чтобы раскрыть соответствующий ivar, который синтезируется компилятором.

Этот метод, кажется, работает, однако, я не уверен, влияю ли я на синтез свойства и ARC каким-то нежелательным образом?

Я использую слабое свойство, чтобы показать, как компилятор заставил меня использовать модификатор __weak с директивой @protected, то есть кажется, что компилятор знает о двух объявлениях и связи между ними.

Суперкласс .h файл

@interface Superclass : NSObject
{
@protected
SCNScene * __weak _scnScene;
}

@end

Суперкласс .m файл

@interface Superclass ()
@property (weak, nonatomic) SCNScene * scnScene;
@end

@implementation Superclass
........
@end

Подкласс .m файл

@implementation Subclass
    // Can use _scnScene just fine
    _scnScene = .....
@end
1
Sulevus 19 Мар 2017 в 00:52

2 ответа

Лучший ответ

Да, это, вероятно, сработает. Не делай так. Это очень негибко. Он заставляет вас объявлять ivars в заголовке, он работает только с ivars и не дает никакого контроля над элементами управления для чтения / записи (или позволяет создавать собственные методы получения / установки). На самом деле больше нет веских оснований для использования средств управления доступом @ (с тех пор как перейти на не хрупкие ивары, и они не были такими полезными раньше).

Типичный способ сделать это с помощью заголовка +Protected с категорией. Например, вы бы создали файл заголовка Superclass+Protected.h следующим образом:

@interface Superclass (Protected)
@property (weak, nonatomic) SCNScene * scnScene;
@end

Затем вы импортируете это в любые файлы реализации, которым разрешен доступ scnScene. Обратите внимание, что вы можете сделать это readonly, если захотите, так что внутренне это доступно для записи, но для защищенных реализаций оно только для чтения, а для общественности - невидимо.

Это более гибкий, чем буквальный «защищенный», потому что вы можете импортировать этот заголовок в любую другую реализацию, где это уместно. Так что это также может быть эквивалентом «друга» в C ++. Очевидно, что присвоение имени файлу и предоставление некоторых комментариев в заголовке может помочь уведомить вызывающих абонентов, должны ли они импортировать этот файл или нет.

На любые жалобы о том, что это не требует контроля доступа (не о том, что вы его сделали, а о тех, кто это делает), ни @protected этого не происходит. Если я позвоню { {X1}}, я также могу получить доступ к защищенным иварам. ObjC помогает вам создавать "запрещенные знаки", чтобы звонящие знали, когда они находятся в местах, которых им не должно быть. Он не пытается остановить программы от доступа к их собственному пространству памяти. (Это было бы бесполезной целью; вы всегда можете читать приватные переменные и вызывать приватные функции на любом языке, который обеспечивает доступ к сырой памяти; цель контроля доступа - помочь вызывающим программам написать правильный код, а не мешать им делать что-либо.)

0
Community 23 Май 2017 в 12:09

В контексте объявления класса protected является видимостью по умолчанию для переменных экземпляра, поэтому ваше объявление не имеет никакого эффекта. На самом деле, следующая декларация:

@interface Superclass : NSObject
@end

Будет иметь точно такой же эффект, как и объявление, которое вы опубликовали, потому что компилятор автоматически синтезирует все необходимые ivars для объявленных свойств, если вы сами не объявите их.

0
jlehr 19 Мар 2017 в 14:04