Objective c 反射设置器方法不工作
我需要使用反射调用setter。要做到这一点,我需要选择器。但是在我的代码中,setterName变量是nil。我班上有二传手和传手。这是我的密码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
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(缓冲区、属性);