Objective c 反射设置器方法不工作

Objective c 反射设置器方法不工作,objective-c,reflection,Objective C,Reflection,我需要使用反射调用setter。要做到这一点,我需要选择器。但是在我的代码中,setterName变量是nil。我班上有二传手和传手。这是我的密码 objc_property_t *allProperties = class_copyPropertyList([object class], &allPropertyCount); objc_property_t prop = class_getProperty(cls, propName); for (unsigned int i = 0

我需要使用反射调用setter。要做到这一点,我需要选择器。但是在我的代码中,setterName变量是nil。我班上有二传手和传手。这是我的密码

objc_property_t *allProperties = class_copyPropertyList([object class], &allPropertyCount);
objc_property_t prop = class_getProperty(cls, propName);
for (unsigned int i = 0; i < allPropertyCount; i++) {

    prop = allProperties[i];

}

char *setterName = property_copyAttributeValue(prop, "S");


SEL selector = NSSelectorFromString(setterName);
if([object respondsToSelector:@selector(selector)]){
    return selector;
}
return nil;
objc\u property\u t*allProperties=class\u copyPropertyList([object class],&allPropertyCount);
objc_property_t prop=class_getProperty(cls,propName);
for(无符号整数i=0;i
仅当属性分别定义自定义setter或getter时,才会设置“S”和“G”属性。代码需要检查
setterName
是否为空,如果为空,则从属性名生成setter名称。

仅当属性分别定义自定义setter或getter时,才设置“S”和“G”属性。您的代码需要检查
setterName
是否为空,如果为空,则从属性名生成setter名称。

回复有点晚,希望这对其他人有用

我已经启用了ARC,并且正在使用生成的getter/setter

//  NSObject+Properties.m
#import "NSObject+Properties.h"
#import "objc/runtime.h"

@implementation NSObject (Properties)

static const char * getPropertyType(objc_property_t property) {

    //Borrowed from http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
    //Many contributors to final solution

    const char *attributes = property_getAttributes(property);
    printf("attributes=%s\n", attributes);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T' && attribute[1] != '@') {
            // it's a C primitive type:
            /*
             if you want a list of what will be returned for these primitives, search online for
             "objective-c" "Property Attribute Description Examples"
             apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
             */
            return (const char *)[[NSData dataWithBytes:(attribute + 1) length:strlen(attribute) - 1] bytes];
        }
        else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
            // it's an ObjC id type:
            return "id";
        }
        else if (attribute[0] == 'T' && attribute[1] == '@') {
            // it's another ObjC object type:
            return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
        }
    }
    return "";
}

- (NSDictionary *) getClassProperties
{
    //Borrowed from http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
    //Many contributors to final solution

    if (self == NULL || self == nil) {
        return nil;
    }

    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            [results setObject:propertyType forKey:propertyName];
        }
    }
    free(properties);

    // returning a copy here to make sure the dictionary is immutable
    return [NSDictionary dictionaryWithDictionary:results];
}

-(void) setProperty:(NSString *) propertyName value:(id) value {

    SEL selector = [self buildGenericSetterForPropertyName:propertyName];

    if( selector != NULL ) {
        //The class responds to the selector
        NSMethodSignature *aSignature = [[self class] instanceMethodSignatureForSelector:selector];
        NSInvocation *anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
        [anInvocation setSelector:selector];
        [anInvocation setTarget:self];
        [anInvocation setArgument:&value atIndex:2];
        [anInvocation invoke];
    }
    else {
        //We don't know what the setter is, so directly access the iVar
        Ivar iVar = class_getInstanceVariable([self class],[propertyName UTF8String]);
        object_setIvar(self, iVar,value);
    }    
}

-(SEL) buildGenericSetterForPropertyName:(NSString *) name {
    //Borrowed from https://github.com/AlanQuatermain/aqtoolkit/blob/master/Extensions/NSObject%2BProperties.m
    NSMutableString * str = [NSMutableString stringWithString: @"set"];
    [str appendString: [[name substringToIndex: 1] uppercaseString]];
    if ( [name length] > 1 )
        [str appendString: [name substringFromIndex: 1]];

    //addition - the setter will accept one argument
    [str appendString:@":"];


    if( [[self class] instancesRespondToSelector:NSSelectorFromString(str)]) {
        return NSSelectorFromString(str);
    }
    else {
        return NULL;
    }
}

@end
//NSObject+Properties.m
#导入“NSObject+Properties.h”
#导入“objc/runtime.h”
@实现对象(属性)
静态常量char*getPropertyType(对象属性){
//借来http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
//最终解决方案的许多贡献者
常量字符*属性=属性\获取属性(属性);
printf(“属性=%s\n”,属性);
字符缓冲区[1+strlen(属性)];
strcpy(缓冲区、属性);
char*state=buffer,*属性;
while((属性=strep(&state,“,”)!=NULL){
如果(属性[0]='T'&&attribute[1]!='@')){
//这是一种C基元类型:
/*
如果您想要这些原语返回内容的列表,请联机搜索
“objective-c”“属性描述示例”
苹果文档列出了很多例子,说明了int“i”、long“l”、unsigned“i”、struct等的用法。
*/
return(const char*)[[NSData dataWithBytes:(属性+1)长度:strlen(属性)-1]字节];
}
else if(属性[0]='T'&&attribute[1]='@'&&strlen(属性)==2){
//这是一种ObjC id类型:
返回“id”;
}
else if(属性[0]='T'&&attribute[1]=='@'){
//这是另一种ObjC对象类型:
return(const char*)[[NSData dataWithBytes:(属性+3)长度:strlen(属性)-4]字节];
}
}
返回“”;
}
-(NSDictionary*)getClassProperties
{
//借来http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
//最终解决方案的许多贡献者
if(self==NULL | | self==nil){
返回零;
}
NSMutableDictionary*results=[[NSMutableDictionary alloc]init];
无符号整数超过,i;
objc_property_t*properties=class_copyPropertyList([self class],&outCount);
对于(i=0;i1)
[str appendString:[name substringFromIndex:1]];
//加法-setter将接受一个参数
[str appendString:@]:;
if([[self class]instanceRespondtoSelector:NSSelectorFromString(str)]){
返回NSSelectorFromString(str);
}
否则{
返回NULL;
}
}
@结束

回复有点晚,希望这对其他人有用

我已经启用了ARC,并且正在使用生成的getter/setter

//  NSObject+Properties.m
#import "NSObject+Properties.h"
#import "objc/runtime.h"

@implementation NSObject (Properties)

static const char * getPropertyType(objc_property_t property) {

    //Borrowed from http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
    //Many contributors to final solution

    const char *attributes = property_getAttributes(property);
    printf("attributes=%s\n", attributes);
    char buffer[1 + strlen(attributes)];
    strcpy(buffer, attributes);
    char *state = buffer, *attribute;
    while ((attribute = strsep(&state, ",")) != NULL) {
        if (attribute[0] == 'T' && attribute[1] != '@') {
            // it's a C primitive type:
            /*
             if you want a list of what will be returned for these primitives, search online for
             "objective-c" "Property Attribute Description Examples"
             apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
             */
            return (const char *)[[NSData dataWithBytes:(attribute + 1) length:strlen(attribute) - 1] bytes];
        }
        else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
            // it's an ObjC id type:
            return "id";
        }
        else if (attribute[0] == 'T' && attribute[1] == '@') {
            // it's another ObjC object type:
            return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
        }
    }
    return "";
}

- (NSDictionary *) getClassProperties
{
    //Borrowed from http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
    //Many contributors to final solution

    if (self == NULL || self == nil) {
        return nil;
    }

    NSMutableDictionary *results = [[NSMutableDictionary alloc] init];

    unsigned int outCount, i;
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    for (i = 0; i < outCount; i++) {
        objc_property_t property = properties[i];
        const char *propName = property_getName(property);
        if(propName) {
            const char *propType = getPropertyType(property);
            NSString *propertyName = [NSString stringWithUTF8String:propName];
            NSString *propertyType = [NSString stringWithUTF8String:propType];
            [results setObject:propertyType forKey:propertyName];
        }
    }
    free(properties);

    // returning a copy here to make sure the dictionary is immutable
    return [NSDictionary dictionaryWithDictionary:results];
}

-(void) setProperty:(NSString *) propertyName value:(id) value {

    SEL selector = [self buildGenericSetterForPropertyName:propertyName];

    if( selector != NULL ) {
        //The class responds to the selector
        NSMethodSignature *aSignature = [[self class] instanceMethodSignatureForSelector:selector];
        NSInvocation *anInvocation = [NSInvocation invocationWithMethodSignature:aSignature];
        [anInvocation setSelector:selector];
        [anInvocation setTarget:self];
        [anInvocation setArgument:&value atIndex:2];
        [anInvocation invoke];
    }
    else {
        //We don't know what the setter is, so directly access the iVar
        Ivar iVar = class_getInstanceVariable([self class],[propertyName UTF8String]);
        object_setIvar(self, iVar,value);
    }    
}

-(SEL) buildGenericSetterForPropertyName:(NSString *) name {
    //Borrowed from https://github.com/AlanQuatermain/aqtoolkit/blob/master/Extensions/NSObject%2BProperties.m
    NSMutableString * str = [NSMutableString stringWithString: @"set"];
    [str appendString: [[name substringToIndex: 1] uppercaseString]];
    if ( [name length] > 1 )
        [str appendString: [name substringFromIndex: 1]];

    //addition - the setter will accept one argument
    [str appendString:@":"];


    if( [[self class] instancesRespondToSelector:NSSelectorFromString(str)]) {
        return NSSelectorFromString(str);
    }
    else {
        return NULL;
    }
}

@end
//NSObject+Properties.m
#导入“NSObject+Properties.h”
#导入“objc/runtime.h”
@实现对象(属性)
静态常量char*getPropertyType(对象属性){
//借来http://stackoverflow.com/questions/754824/get-an-object-attributes-list-in-objective-c
//最终解决方案的许多贡献者
常量字符*属性=属性\获取属性(属性);
printf(“属性=%s\n”,属性);
字符缓冲区[1+strlen(属性)];
strcpy(缓冲区、属性);