Preface
To implement object serialization in iOS, you need to comply with the NSCoding protocol, and then archive and assign values to each property of the object. The response operation is quite cumbersome. This article mainly introduces the use of runtime traversal attributes to greatly simplify the amount of code. Let’s take a look at the detailed introduction below.
The specific implementation code is as follows:
1. First establish the NSobject classification and define the relevant types that may be used
static NSString *intType = @"i"; // int_32t (enumerated int type)static NSString *longTpye = @"l"; //Long Typestatic NSString *longlongType= @"q"; // longlong typestatic NSString *BoolType = @"B"; //bool typestatic NSString *floatType = @"f"; // float static NSString *doubleType = @"d"; // double static NSString *boolType = @"c"; static NSString *stringType = @"NSString"; // NSString typestatic NSString *numberType = @"NSNumber"; // NSNumber typestatic NSString *arrayType = @"arrayType";//array typestatic NSString *imageType = @"UIImage"; // UIImage type
Then, in the archive method, the value corresponding to the property is taken out and the value corresponding to the property is stored locally. At this time, traversing the class attribute itself, Ivar pointer (defining the instance variable of the object, including type and name), the specific code is as follows
// Archive- (void)encodeWithCoder:(NSCoder *)aCoder { unsigned int count; // Number of attributes Ivar *varArray = class_copyIvarList([self class], &count); for (int i = 0; i < count; i++) { Ivar var = varArray[i]; const char *cName = ivar_getName(var); // Attribute name c string NSString *proName = [[NSString stringWithUTF8String:cName] substringFromIndex:1]; //OC string, and remove the underscore _ const char *cType = ivar_getTypeEncoding(var); // Get variable type, c string id value = [self valueForKey:proName]; NSString *proType = [NSString stringWithUTF8String:cType]; // oc string if ([proType containsString:@"NSString"]) { proType = stringType; } if ([proType containsString:@"NSNumber"]) { proType = numberType; } if ([proType containsString:@"NSArray"]) { proType = arrayType; } if ([proType containsString:@"UIImage"]) { proType = imageType; } // (5). Encoding according to type if ([proType isEqualToString:intType] || [proType isEqualToString:boolType] || [proType isEqualToString:BoolType]) { [aCoder encodeInt32:[value intValue] forKey:proName]; } else if ([proType isEqualToString:longTpye]) { [aCoder encodeInt64:[value longValue] forKey:proName]; } else if ([proType isEqualToString:floatType]) { [aCoder encodeFloat:[value floatValue] forKey:proName]; } else if ([proType isEqualToString:longlongType] || [proType isEqualToString:doubleType]) { [aCoder encodeDouble:[value doubleValue] forKey:proName]; } else if ([proType isEqualToString:stringType]) { // string type [aCoder encodeObject:value forKey:proName]; } else if ([proType isEqualToString:numberType]) { [aCoder encodeObject:value forKey:proName]; } else if ([proType isEqualToString:arrayType]) { [aCoder encodeObject:value forKey:proName]; } else if ([proType isEqualToString:imageType]) { // image type [aCoder encodeDataObject:UIImagePNGRepresentation(value)]; } } free(varArray); }
Secondly, unarchive, the principle is similar to archive, directly upload the code
- (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [self init]; if (self) { unsigned int count; Ivar *varArray = class_copyIvarList([self class], &count); for (int i = 0; i < count; i++) { Ivar var = varArray[i]; const char *cName = ivar_getName(var); // Attribute name c string NSString *proName = [[NSString stringWithUTF8String:cName] substringFromIndex:1]; //OC string, and remove the underscore _ const char *cType = ivar_getTypeEncoding(var); // Get variable type, c string NSString *proType = [NSString stringWithUTF8String:cType]; // oc string if ([proType containsString:@"NSString"]) { proType = stringType; } if ([proType containsString:@"NSNumber"]) { proType = numberType; } if ([proType containsString:@"NSArray"]) { proType = arrayType; } if ([proType containsString:@"UIImage"]) { proType = imageType; } if ([proType isEqualToString:intType] || [proType isEqualToString:boolType] || [proType isEqualToString:BoolType]) { int32_t number = [aDecoder decodeInt32ForKey:proName]; [self setValue:@(number) forKey:proName]; } else if ([proType isEqualToString:longTpye]) { int64_t number = [aDecoder decodeInt64ForKey:proName]; [self setValue:@(number) forKey:proName]; } else if ([proType isEqualToString:floatType]) { float number = [aDecoder decodeFloatForKey:proName]; [self setValue:@(number) forKey:proName]; } else if ([proType isEqualToString:longlongType] || [proType isEqualToString:doubleType]) { double number = [aDecoder decodeFloatForKey:proName]; [self setValue:@(number) forKey:proName]; } else if ([proType isEqualToString:stringType]) { // string type NSString *string = [aDecoder decodeObjectForKey:proName]; [self setValue:string forKey:proName]; } else if ([proType isEqualToString:numberType]) { NSString *number = [aDecoder decodeObjectForKey:proName]; [self setValue:number forKey:proName]; } else if ([proType isEqualToString:arrayType]) { NSArray *array = [aDecoder decodeObjectForKey:proName]; [self setValue:array forKey:proName]; } else if ([proType isEqualToString:imageType]) { // image type UIImage *image = [UIImage imageWithData:[aDecoder decodeDataObject]]; [self setValue:image forKey:proName]; } } } return self; }
Finally, it is the storage method, clear the stored local cache and the method of obtaining local stored data.
//Storage path- (NSString *)filePathWithUniqueFlagString:(NSString *)uniqueFlag { NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSString *detailPath = [NSString stringWithFormat:@"%@_%@",uniqueFlag,[NSString stringWithUTF8String:object_getClassName(self)]]; NSString *path = [docPath stringByAppendingPathComponent:detailPath]; return path; } //Save object data to local- (void)saveDataToLocalWithUniqueFlagKey:(NSString *)uniqueFlagKey { [NSKeyedArchiver archiveRootObject:self toFile:[self filePathWithUniqueFlagString:uniqueFlagKey]]; } //Clear the local stored object data- (id)getDataFromLocalWithUniqueFlagKey:(NSString *)uniqueFlagKey { return [NSKeyedUnarchiver unarchiveObjectWithFile:[self filePathWithUniqueFlagString:uniqueFlagKey]]; } //Get object data from local- (BOOL)removeDataFromLocalWithUniqueFlagKey:(NSString *)uniqueFlagKey { NSError *error = nil; [[NSFileManager defaultManager] removeItemAtPath:[self filePathWithUniqueFlagString:uniqueFlagKey] error:&error]; if (!error) { return YES; } else { return NO; } }
The complete project download address is as follows:/maxzhang123/Or you can download the address locally:http://xiazai./201705/yuanma/MXCoding().rar
Summarize
The above is the entire content of this article. I hope the content of this article will be of some help to your study or work. If you have any questions, you can leave a message to communicate. Thank you for your support.