Objective-C свойства - сильные и слабые объявления в категориях

Как среда выполнения Objective-C обрабатывает свойство, которое определено как weak в классе, но частная категория в классе определяет свойство с тем же именем и тип, что и strong?

Будет ли код, запущенный в контексте категории, использовать оригинальный (слабый) модификатор, или он будет использовать модификатор, определенный категорией (сильный)?

Например:

Name.m

@property (weak, nonatomic) NSString *name;

NameTests.m

@interface Name (Test)
@property (strong, nonatomic) NSString *name;
@end

Ответ 1

В объявлении свойства weak применяется только к синтезированному методу установки, если таковая имеется, и синтезированной переменной экземпляра, если таковая имеется. Если ни один из них не синтезирован, то weak не действует.

Если синтезируются переменная setter и instance, возникает вопрос: какое объявление свойства является компилятором, использующим для синтеза переменной setter и instance?

Компилятор никогда не будет синтезировать свойство, объявленное в названной категории. Поэтому в вашем примере name является слабым свойством.

Ответ 2

При добавлении свойств с неоднозначными именами во время выполнения (что происходит, когда вы расширяете класс с категорией), поведение undefined относительно того, какая реализация метода используется.
Это просто столкновение имен, которого можно избежать, префикс вашего метода/свойства категории. Есть несколько подробностей о префиксах в разделе "Ошибки имени метода метода категории" в Apple "Программирование с помощью Objective-C" .

Когда вы создаете простой тестовый проект, вы, вероятно, заметите, что среда выполнения случайно использует одну из двух реализаций. (При тестировании этого избегайте постоянных строк для вашего свойства имени, потому что они не будут выставлять поведение)

Используя расширение класса вместо именованной категории, компилятор будет генерировать ошибку "Недопустимое исправление свойства".