1. 程式人生 > >object-c動態呼叫

object-c動態呼叫

 

採用遞迴的方法訪問一個物件,講其內容寫到一個字典中

支援的成員變數型別:

1,NSString *

2,NSArray *

3,由1,2,構成的自定義類

+ (NSMutableDictionary *) getDicFromObject: (id) theObject

{

if ([theObjectisKindOfClass:[NSStringclass]])

{

return theObject;

}

NSMutableDictionary * tmpDic = [[[NSMutableDictionaryalloc

] init] autorelease];

if (theObject ==nil)

{

return tmpDic;

}

//get all the property fields names

NSString *className =NSStringFromClass([theObject class]);

    const char *cClassName = [className UTF8String];

    id theClass = objc_getClass(cClassName);

unsigned

int outCount, i;

    objc_property_t *properties = class_copyPropertyList(theClass, &outCount);

    NSMutableArray *propertyNames = [[NSMutableArrayalloc] initWithCapacity:1];

    for (i = 0; i < outCount; i++) 

{

        objc_property_t

property = properties[i];

        NSString *propertyNameString = [[NSStringalloc] initWithCString:property_getName(property) 

encoding:NSUTF8StringEncoding]; 

        [propertyNamesaddObject:propertyNameString];

        [propertyNameStringrelease];

       NSLog(@"%s %s\n",property_getName(property), property_getAttributes(property));

    }

for (NSString *keyin propertyNames)

    {

        SEL selector = NSSelectorFromString(key);

        id value = [theObject performSelector:selector];

        if (value == nil)

        {

            value = [NSNullnull];

[tmpDicsetObject:value forKey:key];

continue;

        }

       //[finalDict setObject:value forKey:key];

if ([valueisKindOfClass:[NSStringclass]])

{

[tmpDicsetObject:value forKey:key];

}

elseif ([value isKindOfClass:[NSArrayclass]])

{

NSMutableArray * valueArray = [[[NSMutableArrayalloc] init]autorelease];

NSArray * aArray = (NSArray *)value;

for (int i =0; i < [aArray count]; i++)

{

[valueArrayaddObject:[NetRequestManagergetDicFromObject:[aArray objectAtIndex:i]]];

//[tmpDic setObject:[NetRequestManager getDicFromObject:[aArray objectAtIndex:i]]

//  forKey:key];

}

[tmpDicsetObject:valueArray forKey:key];

}

else 

{

[tmpDicsetObject:[NetRequestManagergetDicFromObject:value] forKey:key];

}

    }

return tmpDic;

}



 



呼叫示例



ContactBaseInfoObj * obj = [[ContactBaseInfoObjalloc] init];

obj.name = [[[NameObjalloc] init]autorelease];

obj.name.firstName =@"Jam";

obj.name.middleName =@"Alen";

obj.name.lastName =@"Green";

obj.primaryEmail =@"America";

NSMutableDictionary * tmpDic = [NetRequestManagergetDicFromObject:obj];

NSString * tmpStr = [tmpDicJSONRepresentation];

NSLog(tmpStr);

NSArray * ids = [NSArrayarrayWithObjects:@"mm",@"Mary", @"yy",nil];

ContactBaseWithBothIDObj * tmpCC = [[ContactBaseWithBothIDObjalloc] init];

tmpCC.contactBaseInfo = obj;

tmpCC.contactID =@"123456";

tmpCC.contactListIDs = ids;

tmpDic = [NetRequestManagergetDicFromObject:tmpCC];

tmpStr = [tmpDicJSONRepresentation];

NSLog(tmpStr);

NSString * testStr = [NetRequestManager getCodeFromObject:obj];

testStr = [NetRequestManager getCodeFromObject:tmpCC];


執行結果


{"primaryEmail":"America","primaryMobile":null,"name":null}


{"primaryEmail":"America","primaryMobile":null,"name":{"firstName":"Jam","middleName":"Alen","lastName":"Green"}}



{"contactID":"123456","contactBaseInfo":{"primaryEmail":"America","primaryMobile":null,"name":{"firstName":"Jam","middleName":"Alen","lastName":"Green"}},"contactListIDs":["mm","Mary","yy"]}



 

     NSLog(@"%s %s\n",property_getName(property), property_getAttributes(property));

可以看到類名,再次

  id theClass = objc_getClass(cClassName);

unsignedint outCount, i;

    objc_property_t *properties = class_copyPropertyList(theClass, &outCount);

    NSMutableArray *propertyNames = [[NSMutableArrayalloc] initWithCapacity:1];

 

就可以得到類結構成員變數的所有屬性,可以通過遞迴的方法來獲取到

一個類的結構可以看成是一個樹結構

 

上面的程式是對任意符合條件的給定類的動態處理方法

可以擴充套件成一個程式碼生成器code maker 來生成一段具體的程式碼來處理一個具體的類,生成的處理程式碼也就是常規的對一個類的處理方式

這個擴充套件還是有些難度的,儘管在理論上是可行的