Будет ли объявление свойства в категории ObjC переопределять свойство с тем же именем, которое объявлено в общедоступном интерфейсе? - PullRequest
0 голосов
/ 06 февраля 2019

Это не предназначено для решения какой-либо конкретной проблемы, просто чтобы понять нюансы свойств в Objc.

скажем, у меня есть класс Dude

# Dude.h

@interface Dude: NSObject

@property (readonly, nonatomic) NSNumber *height;

@end

Я расширяюкласс в файле реализации, но измените атрибуты.

# Dude.m

@interface Dude()

@property (readwrite, atomic) NSNumber *height;

@end


@implementation Dude
@end

Я получаю ошибку.

Атрибут 'atomic' в свойстве 'height' не соответствует свойству, унаследованному от 'Dude'

Так что на самом деле здесь происходит.Является ли свойство расширения таким же свойством?Я просто переопределяю методы доступа?

Также, когда я изменяю порядок так, чтобы общедоступный интерфейс был readwrite, а частный интерфейс - readonly Я получаю ошибку:

Недопустимая переопределение свойства в расширении класса «Чувак» (атрибут должен быть «readwrite», а его основной должен быть «readonly»)

Это заставляет меня думать, что это полное переопределение, но теперь я менее уверено том, что на самом деле происходит.Нужны уточнения.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

В Apple Языке программирования Objective C они описывают «расширения» следующим образом, используя переопределение свойства в качестве примера:

Расширения

Расширения классов похожи на анонимные категории, за исключением того, что методы, которые они объявляют, должны быть реализованы в основном блоке @implementation для соответствующего класса.Используя компилятор Clang / LLVM 2.0, вы также можете объявлять свойства и переменные экземпляра в расширении класса.

Распространенное использование расширений класса заключается в том, чтобы повторно объявить свойство, публично объявленное как доступное только для чтения, как readwrite:

@interface MyClass : NSObject
@property (retain, readonly) float value;
@end

// Private extension, typically hidden in the main implementation file.
@interface MyClass ()
@property (retain, readwrite) float value;
@end

...

Итак, как показано здесь, этот шаблон предназначен для «повторного объявления» свойства.Это то же свойство, хотя.Вы повторно определяете свойство только тогда, когда хотите, чтобы компилятор синтезировал частный установщик, даже если открытый интерфейс объявлен как readonly.Если вы не переопределите свойство как readwrite в расширении, сеттер не будет синтезироваться вообще.

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

0 голосов
/ 06 февраля 2019

Вы можете думать об этом больше как о публичном и частном интерфейсе.

Интерфейс, объявленный в файле .h, является публичным интерфейсом для вашего класса.Поэтому, если у вас есть причина объявить свойство только для чтения, это имеет смысл.

Безымянная категория (Dude ()) в вашем файле .m - это ваше личное представление о свойствах.Таким образом, вы можете указать readwrite здесь, чтобы ваш класс мог изменять свойство внутри, но не во внешнем мире.

Вы также можете использовать это объявление для своих методов, чтобы объявить открытый интерфейс в .h и закрытые методы вinterface Dude () в .m.

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

И наконец, это Objective-C: это только для вашего редактора и компилятора.Ко всему существующему можно получить доступ, даже если оно объявлено каким-то частным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...