property_getAttributes() не делает различий между сохранением, сильным, слабым и назначением свойств, когда установлено только для чтения

Я пытаюсь получить атрибуты свойства объекта с помощью функции времени выполнения property_getAttributes(). Некоторые свойства доступны только для чтения. Но проблема возникает, когда я пытаюсь сделать разницу между сохранением / сильным, слабым и назначением свойств. например:

Допустим, у нас есть:

@interface MyObject : NSObject
@property (assign, readonly) NSObject *prop1;
@property (strong, readonly) NSObject *prop2;
@property (weak, readonly) NSObject *prop3;
@end

Получаем список недвижимости и печатаем

int outCount;
objc_property_t *properties = class_copyPropertyList([MyObject class], &outCount);
for(i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    const char *c_attributes = property_getAttributes(property);
    printf("%s", c_attributes);
}
free(properties);

Результат:

T@"NSObject",R,V_prop1
T@"NSObject",R,V_prop2
T@"NSObject",R,V_prop3

... так что нет специального кода для слабых, сильных / сохраняемых, присваивайте свойства, когда они доступны только для чтения:(

Вопрос в следующем: есть ли другой способ узнать, является ли свойство слабым, сильным / сохранить, назначить?

2 ответа

Я не пробовал ваш код, но согласно

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/objcruntimeguide/articles/ocrtpropertyintrospection.html

R Свойство только для чтения (только для чтения)

C Свойство является копией последнего назначенного значения (копия).

& Свойство является ссылкой на значение, присвоенное последним (сохранить).

N Свойство неатомарное (неатомарное).

G Свойство определяет произвольное имя селектора геттера. Имя следует за буквой G (например, GcustomGetter,).

S Свойство определяет имя селектора пользовательского установщика. Имя следует за буквой S (например, ScustomSetter:,).

D Свойство является динамическим (@dynamic).

W Свойство является слабой ссылкой (__weak).

P Собственность имеет право на сбор мусора.

t Определяет тип с использованием кодировки старого стиля.

Чтобы ответить на ваш вопрос быстро, ответ - нет.

Проблема здесь в том, что семантика управления памятью для свойств (это assign, unsafe_unretained, strong, weak, copy в АРК и assign, retain, copy в MRC) есть только применение автоматически сгенерированного установочного кода. Если вы пишете свой собственный установщик для свойства, вам, конечно, рекомендуется реализовать семантику самостоятельно (но не обязательно). Получатель этих свойств вообще не изменяется этими атрибутами свойства. Рассмотрим этот код:

@interface FooBar ()
@property (nonatomic, strong, readonly) NSString* foobar;
@end

@implementation FooBar
- (NSString*) foobar {
    return [NSString stringWithFormat:@"aString"];
}

В этих ситуациях вызывающая сторона будет использовать либо сильную, либо слабую ссылку, а возвращаемое значение должно жить как минимум столько времени, сколько требуется вызывающему коду для завершения оператора. В случае слабой ссылки это пойдет на nil впоследствии, так как собственность с strong не гарантирует, что указанный объект будет сохранен для вас. В конечном счете, управление памятью на readonly свойства - это не что иное, как плацебо, которое заканчивается в основном привычкой или стилем @property (nonatomic, readonly) ... совершенно законно, но сбивает с толку, когда мы привыкли встречать атрибут памяти в объявлении свойства.

PS: во время выполнения есть еще одна функция, которая называется property_copyAttributeList который я нахожу гораздо проще для анализа этой информации (он использует структуры, чтобы разбить компоненты для вас).

Другие вопросы по тегам