Assign values to the model using a dictionary and support replacement of map key values
This is an upgraded version of yesterday's tutorial, supporting map replacement of key values.
The source code is as follows:
Nsobject + properties. h and nsobject + properties. m
/// Nsobject + properties. h /// created by youxianming on 14-9-4. // copyright (c) 2014 youxianming. all rights reserved. // # import <Foundation/Foundation. h> @ interface nsobject (properties) @ property (nonatomic, strong) nsdictionary * mapdictionary;-(void) setdatadictionary :( nsdictionary *) datadictionary;-(nsdictionary *) datadictionary; @ end
/// Nsobject + properties. M /// created by youxianming on 14-9-4. // copyright (c) 2014 youxianming. all rights reserved. // # import "nsobject + properties. H "# import <objc/runtime. h> @ implementation nsobject (properties) # pragma runtime-an attribute is added dynamically. The map attribute is static char mapdictionaryflag;-(void) setmapdictionary :( nsdictionary *) mapdictionary {aggregate (self, & mapdictionaryflag, mapdictionary, region) ;}- (nsdictionary *) mapdictionary {return objc_getassociatedobject (self, & mapdictionaryflag) ;}# Pragma public-public method-(void) setdatadictionary :( nsdictionary *) datadictionary {[self setattributes: [self mapdictionary: Self. mapdictionary datadictionary: datadictionary] OBJ: Self];}-(nsdictionary *) datadictionary {// obtain the attribute list nsarray * properties = [self propertynames: [self class]; // obtain the property value from the attribute list. Return [self propertiesandvaluesdictionary: Self properties: properties];} # pragma private-private method // splice the setter method with the property name-(SEL) getsetterselwithattibutename :( nsstring *) attributename {nsstring * capital = [[attributename substringtoindex: 1] uppercasestring]; nsstring * setterselstr = [nsstring stringwithformat: @ "set % @:", capital, [attributename substringfromindex: 1]; return nsselectorfromstring (setterselstr);} // set the attribute value through the dictionary-(void) setattributes :( nsdictionary *) datadic OBJ :( ID) OBJ {// obtain all key values nsenumerator * keyenum = [datadic keyenumerator]; // The dictionary key value (one-to-one correspondence with the model attribute value) ID attributename = nil; while (attributename = [keyenum nextobject]) {// get the assembled setter method sel = [OBJ getsetterselwithattibutename: attributename]; // verify whether the setter method can respond to If ([OBJ respondstoselector: sel]) {id value = nil; Id tmpvalue = datadic [attributename]; If ([tmpvalue iskindofclass: [nsnull class]) {// if it is of the nsnull type, the value is null value = nil;} else {value = tmpvalue;} // execute the setter method [OBJ =mselecw.mainthread: sel withobject: Value waituntildone: [nsthread ismainthread] ;}}// get the attribute name list of a class-(nsarray *) propertynames :( class) class {nsmutablearray * propertynames = [[nsmutablearray alloc] init]; unsigned int propertycount = 0; optional * properties = class_copypropertylist (class, & propertycount); For (unsigned int I = 0; I <propertycount; ++ I) {objc_property_t property = properties [I]; const char * name = property_getname (property); [propertynames addobject: [nsstring stringwithuf8string: Name];} free (properties); Return propertynames;} // obtain the value of this attribute based on the attribute array-(nsdictionary *) propertiesandvaluesdictionary :( ID) OBJ properties :( nsarray *) properties {nsmutabledictionary * propertiesvaluesdic = [nsmutabledictionary dictionary]; for (nsstring * property in properties) {sel getsel = nsselectorfromstring (property); If ([OBJ respondstoselector: getsel]) {nsmethodsignature * Signature = nil; Signature = [OBJ sequence: getsel]; nsinvocation * invocation = [nsinvocation sequence: Signature]; [invocation settarget: OBJ]; [invocation setselector: getsel]; nsobject * _ unsafe_unretained valueobj = nil; [invocation invoke]; [invocation getreturnvalue: & valueobj]; // assign to @ "" string if (valueobj = nil) {valueobj = @ "";} propertiesvaluesdic [property] = valueobj;} return propertiesvaluesdic;} // Replace the key value with the MAP value-(nsdictionary *) mapdictionary :( nsdictionary *) map datadictionary :( nsdictionary *) Data {If (MAP & Data) {// copy the dictionary nsmutabledictionary * newdatadic = [nsmutabledictionary dictionarywithdictionary: Data]; // obtain all MAP key values nsarray * allkeys = [map allkeys]; for (nsstring * oldkey in allkeys) {// obtain value id value = [newdatadic objectforkey: oldkey]; // if the value if (value) {nsstring * newkey = [map objectforkey: oldkey]; [newdatadic removeobjectforkey: oldkey]; [newdatadic setobject: Value forkey: newkey] ;}} return newdatadic;} else {return data ;}}@ end
Note:
Here, a new attribute named mapdictionary is added to the category of nsobject.
Then add an attribute named memberid to member.
The following are usage cases:
//// Appdelegate. M // runtime /// created by youxianming on 14-9-5. // copyright (c) 2014 youxianming. all rights reserved. // # import "appdelegate. H "# import" nsobject + properties. H "# import" model. H "@ implementation appdelegate-(bool) Application :( uiapplication *) Application didfinishlaunchingwitexceptions :( nsdictionary *) launchoptions {// initialize model * model = [model new]; // set the MAP value model. mapdictionary =@{@ "ID": @ "memberid"}; // assign a value to the model through the dictionary. datadictionary =@ {@ "name": @ "youxianming", @ "Age": @ 26, @ "addressinfo": @ {@ "Hubei": @ "Weihan "}, @ "events": @ [@ "one", @ "two", @ "three"], @ "ID": @ "7788 "}; // print the nslog (@ "% @", model. datadictionary); Return yes;} @ end
The procedure is as follows:
Assign values to the model using a dictionary and support replacement of map key values