Обходное решение для выполнения защищенных свойств в Objective-C
Я пытаюсь найти обходное решение для объявления @protected свойств в Objective-C, поэтому доступ к ним могут только подклассы в иерархии (только для чтения, а не для записи).
Я читал, что нет документального способа сделать это, поэтому я подумал об этом обходном пути, и я хотел спросить мнение StackOverflow об этом.
Каждый пользовательский класс в верхней части иерархии содержит три класса, одну реализацию и два интерфейса.
Назовите их:
ClassA.h
ClassA_protected.h
ClassA.m
Тогда любой подкласс этого класса A будет как обычно:
ClassB.h
ClassB.m
Сначала я создал интерфейс ClassA.h, где объявляю защищенную переменную int, чтобы любой подкласс ClassA мог иметь к ней доступ:
@interface ClassA : NSObject{
@protected
int _myProtectedInt;
}
@end
Следующий шаг - обходной путь, о котором я говорил. Однако, прочитав это, вы увидите, что это довольно прямолинейно. Я объявила второй интерфейс под названием ClassA_protected.h, который фактически работает как расширение класса Class.h и позволяет нам помечать свойство как readonly
:
#import "ClassA.h"
@interface ClassA ()
@property (nonatomic , readonly) int myProtectedInt;
@end
Последний шаг подготовки защищенной иерархии - объявить ее реализацию в ClassA.m, где мы только синтезируем наше свойство:
#import "ClassA_protected.h"
@implementation ClassA
@synthesize myProtectedInt = _ myProtectedInt;
@end
Таким образом, каждый класс, который должен быть подклассом ClassA.h, импортирует ClassA_protected.h. Таким образом, такой ребенок, например ClassB.h, будет следующим:
#import "ClassA_protected.h"
@interface ClassB : ClassA
@end
И пример доступа к этому свойству из реализации ClassB.m:
@implementation ClassB
-(void) method {
//edit protected variable
_myProtectedInt= 1;
//normal access
self.muProtectedInt;
}
@end
Ответы
Ответ 1
Конечно, это прекрасно работает. Apple использует тот же подход, например, в классе UIGestureRecognizer
. Подклассам необходимо импортировать дополнительный файл UIGestureRecognizerSubclass.h
и переопределить методы, объявленные в этом файле.
Ответ 2
Для простых "свойств" просто используйте ivar. Это так же хорошо, как и свойства для всех практических целей.
Кроме того, значение по умолчанию уже защищено.
Ответ 3
Если вы попросите мнение, это мое: если вы решите изменить ваш
_myProtectedInt
он, вероятно, будет преуспевать, потому что это определенно возможно с Objective-C временем выполнения. Кроме этого, ваше решение в порядке.