Benefits-& gt; KVC + Runtime: Get the attributes, member variables, methods, and protocols of classes/objects and implement dictionary-to-model conversion. kvcruntime

Source: Internet
Author: User
Tags allkeys

Benefits-> KVC + Runtime: Get the attributes, member variables, methods, and protocols of classes/objects and implement dictionary-to-model conversion. kvcruntime

We know that KVC + Runtime can do a lot of things. With this, we can achieve a lot of results.

Here we provide a benefit. We use KVC + Runtime to obtain all member variables, attributes, methods, and protocols of classes/objects;

And use it to implement dictionary-to-model conversion.

If you don't talk much about it, go directly to the Code:

1. Tool class (actually a classification of NSObject) header file

1 # import <Foundation/Foundation. h> 2 3 @ interface NSObject (YSRuntime) 4 5/** 6 return the attribute array of the current Class 7 8 @ return attribute array (for example, "name", "age ", "address") 9 */10 + (NSArray *) ys_propertiesList; 11 12/** 13 return the member variable array of the current class 14 15 @ return member variable array 16 */17 + (NSArray *) ys_ivarsList; 18 19/** 20 return the object method array of the current class 21 22 @ return method array 23 */24 + (NSArray *) ys_methodList; 25 26/** 27 return the Protocol array of the current Class 28 29 @ return protocol array 30 */31 + (NSArray *) ys_protocolList; 32 33/** 34 use the dictionary to create the object of the current class 35 36 @ param dictionary 37 38 @ return the object of the current class 39 */40 + (instancetype) ys_objectWithDictionary :( NSDictionary *) dictionary; 41 42/** 43 create an object array of the current class using a dictionary array 44 45 @ param dictArray dictionary array 46 47 @ return object array of the current class 48 */49 + (NSArray *) ys_objectsWithDictionaryArray :( NSArray <NSDictionary *> *) dictArray; 50 51 @ end

2. Next we will implement the method in it and use it to obtain the attributes, member variables, methods, and protocols of classes/objects.

Note: The most important method is in objc/runtime. h. Here we only list some of them and play a role in attracting others.

1 # import "NSObject + YSRuntime. h "2 # import <objc/runtime. h> 3 4 @ implementation NSObject (YSRuntime) 5 6 # pragma mark-attribute array 7 const char * propertiesKey = "ys. propertiesList "; 8 + (NSArray *) ys_propertiesList {9 10 // get the associated object 11 NSArray * result = objc_getAssociatedObject (self, propertiesKey); 12 13 if (result! = Nil) {14 return result; 15} 16 17 unsigned int count = 0; 18 objc_property_t * list = class_copyPropertyList ([self class], & count ); 19 20 NSMutableArray * arrayM = [NSMutableArray array]; 21 22 for (unsigned int I = 0; I <count; I ++) {23 24 objc_property_t pty = list [I]; 25 26 const char * cName = property_getName (pty); 27 NSString * name = [NSString stringwithuf8string: cName]; 28 29 [arrayM add Object: name]; 30} 31 32 free (list); 33 34 // set the correlated Object 35 objc_setAssociatedObject (self, propertiesKey, arrayM, objects); 36 37 return objc_getAssociatedObject (self, propertiesKey); 38} 39 40 # pragma mark-Private method, specifically for custom attributes in the dictionary-to-model, {@ "name": @ "Dog "}, name is the property name, Dog is the custom model class, and property name-attribute type 41 const char * propertiesTypeKey = "ys. propertiesTypeKey "; 42 + (NSArray <NSDictionary *> *) ys_propert IesAndTypeList {43 44 // get the correlated object 45 NSArray * result = objc_getAssociatedObject (self, propertiesTypeKey); 46 47 if (result! = Nil) {48 return result; 49} 50 51 unsigned int count = 0; 52 objc_property_t * list = class_copyPropertyList ([self class], & count ); 53 54 NSMutableArray <NSDictionary *> * arrayM = [NSMutableArray <NSDictionary *> array]; 55 56 for (unsigned int I = 0; I <count; I ++) {57 58 objc_property_t pty = list [I]; 59 60 const char * cType = property_getAttributes (pty); 61 NSString * typeStr = [NSString strin GWithUTF8String: cType]; 62 63 if ([typeStr containsString: @ "\", & "]) {64 nsange typeRange = [typeStr rangeOfString: @" \ ", &"]; 65 NSString * type = [typeStr substringWithRange: NSMakeRange (3, typeRange. location-3)]; 66 67 const char * cName = property_getName (pty); 68 NSString * name = [NSString stringwithuf8string: cName]; 69 70 NSDictionary * dict =@{ name: type}; 71 72 [arrayM addObject: dict]; 73} 74} 75 76 free (list); 77 78 // set the correlated object 79 objc_setAssociatedObject (self, propertiesTypeKey, arrayM, callback); 80 81 return objc_getAssociatedObject (self, propertiesTypeKey ); 82} 83 84 85 # pragma mark-member variable array 86 const char * ivarsKey = "ys. ivarsList "; 87 + (NSArray *) ys_ivarsList {88 89 // get the associated object 90 NSArray * result = objc_getAssociatedObject (self, ivarsKey); 91 92 if (result! = Nil) {93 return result; 94} 95 96 unsigned int count = 0; 97 Ivar * list = class_copyIvarList ([self class], & count ); 98 99 NSMutableArray * arrayM = [NSMutableArray array]; 100 101 for (unsigned int I = 0; I <count; I ++) {102 103 Ivar ivar = list [I]; 104 105 const char * cName = ivar_getName (ivar); 106 NSString * name = [NSString stringwithuf8string: cName]; 107 108 [arrayM addObject: name]; 109} 110 111 free (list); 112 113 // set the correlated object 114 objc_setAssociatedObject (self, ivarsKey, arrayM, callback); 115 116 return objc_getAssociatedObject (self, ivarsKey ); 117} 118 119 # pragma mark-Method array 120 + (NSArray *) ys_methodList {121 122 unsigned int count = 0; 123 Method * list = class_copyMethodList ([self class], & count); 124 125 NSMutableArray * arrayM = [NSMutableArray array]; 126 127 for (unsigned int I = 0; I <count; I ++) {128 129 Method method = list [I]; 130 131 SEL selector = method_getName (method); 132 NSString * name = NSStringFromSelector (selector); 133 134 [arrayM addObject: name]; 135} 136 137 free (list); 138 139 return arrayM. copy; 140} 141 142 # pragma mark-Protocol array 143 + (NSArray *) ys_protocolList {144 145 unsigned int count = 0; 146 _ unsafe_unretained Protocol ** list = class_copyProtocolList ([self class], & count); 147 148 NSMutableArray * arrayM = [NSMutableArray array]; 149 150 for (unsigned int I = 0; I <count; I ++) {151 152 Protocol * protocol = list [I]; 153 154 const char * cName = protocol_getName (protocol); 155 NSString * name = [NSString stringwithuf8string: cName]; 156 157 [arrayM addObject: name]; 158} 159 160 free (list); 161 162 return arrayM. copy; 163} 164 165 # pragma mark-dictionary-> Object of the current class 166 + (instancetype) ys_objectWithDictionary :( NSDictionary *) dictionary {167 168 // attribute array of the current class 169 NSArray * list = [self ys_propertiesList]; 170 171 NSArray <NSDictionary *> * propertyTypeList = [self ys_propertiesAndTypeList]; 172 173 id obj = [self new]; 174 175 for (NSString * key in dictionary) {176 177 if ([list containsObject: key]) {178 179 if ([dictionary [key] isKindOfClass: [NSDictionary class]) {// The attribute value is dictionary 180 181 for (NSDictionary * dict in propertypelist) {182 183 if ([key isEqualToString: [NSString stringWithFormat: @ "% @", dict. allKeys. firstObject]) {184 185 NSString * classTypeStr = dict [key]; 186 Class class = NSClassFromString (classTypeStr); 187 188 id objChild = [class ys_objectWithDictionary: dictionary [key]; 189 190 [obj setValue: objChild forKey: key]; 191} 192 193 194} 195 else if ([dictionary [key] isKindOfClass: [NSArray <NSDictionary *> class]) {// The attribute value is the dictionary array 196 197} 198 else {199 [obj setValue: dictionary [key] forKey: key]; 200} 201} 202 203 return obj; 205} 206 207 # pragma mark-dictionary array-> current Class Object array 208 + (NSArray *) ys_objectsWithDictionaryArray :( NSArray <NSDictionary *> *) dictArray {209 210 if (dictArray. count = 0) {211 return nil; 212} 213 214 // attribute array of the current class 215 NSArray * list = [self ys_propertiesList]; 216 NSArray <NSDictionary *> * propertyTypeList = [self ys_propertiesAndTypeList]; 217 218 NSMutableArray * arrayM = [NSMutableArray array]; 219 for (NSDictionary * dictionary in dictArray) {221 222 id obj = [self new]; 223 224 for (NSString * key in dictionary) {225 226 if ([list containsObject: key]) {227 228 if ([dictionary [key] isKindOfClass: [NSDictionary class]) {// The attribute value is dictionary 229 230 for (NSDictionary * dict in propertypelist) {231 232 if ([key isEqualToString: [NSString stringWithFormat: @ "% @", dict. allKeys. firstObject]) {233 234 NSString * classTypeStr = dict [key]; 235 Class class = NSClassFromString (classTypeStr); 236 237 id objChild = [class ys_objectWithDictionary: dictionary [key]; 238 239 [obj setValue: objChild forKey: key]; 240} 241 242 243} 244 else if ([dictionary [key] isKindOfClass: [NSArray <NSDictionary *> class]) {// The attribute value is the dictionary array 245 246} 247 else {248 [obj setValue: dictionary [key] forKey: key]; 249} 250} 251 252 253 [arrayM addObject: obj]; 254} 255 256 return arrayM. copy; 257} 258 259 @ end

 

3. Like YYModel, if one property of an object is another custom object, it can also act as a reconnection;

4. Unfortunately, it is the same as YYModel. If an attribute is an array and a generic constraint is added, the generic constraint of this array is not obtained.

I remember, YYModel has this problem. Because generic constraints cannot be obtained, You need to manually specify the element type in the array when the attribute is an array.

I hope you will not be enlightened after seeing this.

 

5. Finally, I posted a small and very interesting little stuff. The key in it is that I used "ys_ivarsList" to get all the member variables, and then found the member _^ at the first level.

1 // set the random color to the statusBar of the Application. Therefore, the mother no longer needs to worry about the background color of statusBar. 2 id bgStyle = [[UIApplication sharedApplication] valueForKeyPath: @ "statusBar. backgroundView. style "]; 3 [bgStyle setValue: [UIColor redColor] forKey: @" backgroundColor "];
1 // frame = (5 649; 55 13) 2 // modify AMAP and logo, Delete and replace your own custom 3 UIImageView * imgV = [mapView valueForKey: @ "logoImageView"]; // This is the logo4 imgV of AMAP. image = nil; // set the imageView image to nil5 [mapView setValue: imgV forKey: @ "logoImageView"]; // Haha, the logo of this AMAP disappears, mom no longer needs to worry about the logo.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.