Как определить свойства метода получения / установки метода выбора, используя отражение времени выполнения в Objective-C?(или наоборот) - PullRequest
4 голосов
/ 11 декабря 2011

Objective-C предлагает функцию отражения во время выполнения. Я пытаюсь найти имя получателя / установщика селектора объявленного свойства. Я знаю основное правило, подобное field / setField:. В любом случае, я думаю, что отражение во время выполнения должно предлагать функцию для разрешения имени для полной абстракции, но я не смог найти функцию.

Как я могу разрешить метод получения / установки селектор (не реализация) объявленного свойства с отражением во время выполнения в Objective-C (на самом деле Apple, Какао)

Или обратный запрос. (селектор метода → объявленное свойство)

Ответы [ 2 ]

8 голосов
/ 11 декабря 2011

Я думаю, что вы можете получить имена селекторов, только если свойство объявлено с явным (setter = XXX и / или getter = XXX)

Таким образом, чтобы получить имена селекторов getter и setter для некоторого свойства 'furType'класса' Cat ':

objc_property_t prop = class_getProperty([Cat class], "furType");

char *setterName = property_copyAttributeValue(prop, "S");
if (setterName == NULL) { /*Assume standard setter*/ }

char *getterName = property_copyAttributeValue(prop, "G");
if (getterName == NULL) { /*Assume standard getter */ }

Я не знаю обратного запроса, кроме как перебирать все свойства и искать совпадения.Надеюсь, это поможет.

1 голос
/ 04 августа 2016

Небольшое обновление из моей категории NSObject. Надеюсь, это кому-нибудь поможет:

+(SEL)getterForPropertyWithName:(NSString*)name {
    const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    objc_property_t prop = class_getProperty(self, propertyName);

    const char *selectorName = property_copyAttributeValue(prop, "G");
    if (selectorName == NULL) {
        selectorName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    }
    NSString* selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
    return NSSelectorFromString(selectorString);
}

+(SEL)setterForPropertyWithName:(NSString*)name {
    const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
    objc_property_t prop = class_getProperty(self, propertyName);

    char *selectorName = property_copyAttributeValue(prop, "S");
    NSString* selectorString;
    if (selectorName == NULL) {
        char firstChar = (char)toupper(propertyName[0]);
        NSString* capitalLetter = [NSString stringWithFormat:@"%c", firstChar];
        NSString* reminder      = [NSString stringWithCString: propertyName+1
                                                     encoding: NSASCIIStringEncoding];
        selectorString = [@[@"set", capitalLetter, reminder, @":"] componentsJoinedByString:@""];
    } else {
        selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
    }

    return NSSelectorFromString(selectorString);
}
...