ObjC学习11-复制对象与归档
来源:互联网 发布:孙悟空kingking淘宝店 编辑:程序博客网 时间:2024/06/06 19:27
1.复制对象
Foundation类实现了名为copy和mutableCopy的方法 可以用这些方法来创建对象的副本。
代码实例:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //NSLog(@"1326"); NSMutableArray *dArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"c",@"d",nil]; NSMutableArray *dArray2 ; dArray2 = dArray; [dArray2 removeObjectAtIndex:0]; NSLog(@"dArray:"); for(NSString *elem in dArray) { NSLog(@"%@",elem); } NSLog(@"dArray2:"); for(NSString *elem2 in dArray2) { NSLog(@"%@",elem2); } dArray2 = [dataArray mutableCopy]; [dArray2 removeObjectAtIndex:0]; NSLog(@"dArray:"); for(NSString *elem in dArray) { NSLog(@"%@",elem); } NSLog(@"dArray2:"); for(NSString *elem2 in dArray2) { NSLog(@"%@",elem2); } [pool drain];在win下的开发环境编译出错,这个错误暂时没解决,代码逻辑上是没错的,有时间再xcode下去跑一遍,
结果是:赋值的数组传的是指针引用 remove后 双方原先的索引0的字符串没有了,而赋值的数组将是以对象的形式存在于dArray2,删除索引0而不影响到原数组。
此外还可以通过实现<NSCopying>及<NSMutableCopying>协议来实现复制对象。
如:@interface F:NSObject<NSCopying> 你们F.m中就必须添加方法 -(id) copyWith:(NSzone*) zone{...}
还可以用复制方法和取值方法复制对象:只要实现复制方法或是取值方法,都应考虑变量中存储的内容、要检索的内容以及时候需要保护这些值。
-(void) setName:(NSString *)theName{name = [theName copy];}//当然,要使赋值方法的内存管理更友好一些,首先应该释放旧的值-(void) setName:(NSString *)theName{[name autorelease];name = [theName copy];}
//property声明@property (nonatomic,copy) NSString *name;//会生成一个合并的方法,其类型类似于:-(void) setName :(NSString *) theName{ if(theName!=name) { [name = release]; name = [theName copy];}
这里使用nonatomic(默认是atomic)是为了告诉系统不要使用mutex(互斥)锁定保护属性存取器方法这种方法会在设置新值时释放变量的旧值,确保旧的值不会被销毁。如果在多线程环境中运行,需要考虑使用atomic存取器方法。
简单总结就是赋值的实例变量实际是原变量的引用,而复制的对象变量是它的完整副本。
2.归档
归档是指用某种个性来保存一个或多个对象,以便以后还原这些对象的过程。(类似序列化~)
2.1使用XML属性列表进行归档 以key -value键值对写入文件
NSDictionary *glossary=[NSDictionary dictionaryWithObjectsAndKeys: @"a",@"aaa",@"b",@"bbb",@"c",@"ccc",nil]; if([glossary writeToFile:@"glossary"atomically:YES]==NO) { NSLog(@"save failed!"); }
atomically:YES这里是为字典写入文件创建一个glossary临时备份文件,若一旦成功将把数据转移到名为glossary的指定文件中。
在win开发环境下最后生成的程序文件不是XML文件这点等在xcode下再测一遍=.=要将文件中的内容读入程序,可以用dictionaryWithContentsOfFile:或arrayWithContentsOfFile:方法。读回数据可使用dataWithContentsOfFile:,读回字符串对象可使用stringWithContentsOfFile:方法。
NSDictionary *g; g= [NSDictionary dictionaryWithContentsOfFile :@"glossary"]; for(NSString *k in g) { NSLog(@"%@:%@",[g objectForKey:k]); }2.2使用NSKeyedArchiver归档 以带键key的文档把对象存入文件中
在IPhone中使用归档功能必须使用NSKeyedArchiver<Foundation/NSKeyedArchiver.h>
NSDictionary *glossary=[NSDictionary dictionaryWithObjectsAndKeys: @"aa",@"aaa",@"bb",@"bbb",@"cc",@"ccc",nil]; [NSKeyedArchiver archiveRootObject:glossary toFile:@"glossary.archive"];把字典对象归档到当前目录下,也可以通过NSKeyedUnarchiver的unArchiveObjectWithFile:方法把创建的归档读入程序中。
NSDictionary *glossary; glossary=[NSKeyedUnarchiver unArchiveObjectWithFile:@"glossary.archive"];在辉旭glossary后,程序可以通过枚举祺内容来验证恢复是否成功~
2.3编码和解码
通常自定义类对象不能直接归档,必须告知系统如何归档(或编码)你的对象,以及如何解归档(解码)它们。必须遵守<NSCoding>协议,在类定义中添加encodeWithCoder: 方法和initWithCoder: 方法以实现归档对象和恢复对象。
在带键的档案中编码和解码基本数据类型:
编码方法
解码方法
encodeBool: forKey
decodeBool: forKey
encodeInt: forKey
decodeInt: forKey
encodeInt31: forKey
decodeInt32: forKey
encodeInt64: forKey
decodeInt64: forKey
encodeFloat: forKey
decodeFloat: forKey
encodeDouble: forKey
decodeDouble: forKey
encodeObject:forKey:和decodeObjectforKey:编码和解
//Addresscard.h Interface File#import <Foundation/Foundation.h>@interface AddressCard : NSObject<NSCopying,NSCoding> {NSString *name;NSString *email;}@property (nonatomic, copy) NSString *name, *email;-(void) setName: (NSString *) theNameandEmail: (NSString *) theEmail;-(void) retainName: (NSString *) theNameandEmail: (NSString *) theEmail;-(NSComparisonResult) compareNames: (id) element;-(void) print;@end#import "AddressCard.h"@implementation AddressCard@synthesize name, email;-(void) setName: (NSString *) theNameandEmail: (NSString *) theEmail{[self setName: theName];[self setEmail: theEmail];}// Compare the two names from the specified address cards-(NSComparisonResult) compareNames: (id) element{return [name compare: [element name]];}-(void) print{NSLog (@"====================================");NSLog (@"| |");NSLog (@"| %-31s |", [name UTF8String]);NSLog (@"| %-31s |", [email UTF8String]);NSLog (@"| |");NSLog (@"| |");NSLog (@"| |");NSLog (@"| O O |");NSLog (@"====================================");}-(AddressCard *) copyWithZone: (NSZone *) zone{AddressCard *newCard = [[AddressCardallocWithZone: zone] init]; [newCardretainName: name andEmail: email]; return newCard;}-(void) retainName: (NSString *) theNameandEmail: (NSString *) theEmail{ name = [theName retain]; email = [theEmail retain];}-(void) encodeWithCoder: (NSCoder *) encoder{ [encoder encodeObject: name forKey: @"AddressCardName"]; [encoder encodeObject: email forKey: @"AddressCardEmail"];}-(id) initWithCoder: (NSCoder *) decoder{ name = [[decoder decodeObjectForKey: @"AddressCardName"] retain]; email = [[decoder decodeObjectForKey: @"AddressCardEmail"] retain]; return self;}-(void) dealloc{ [name release]; [email release]; [super dealloc];}@end
#import "AddressCard.h"@interface AddressBook: NSObject<NSCopying,NSCoding>{NSString *bookName;NSMutableArray *book;}@property (nonatomic, copy) NSString *bookName;@property (nonatomic, copy) NSMutableArray *book;-(id) initWithName: (NSString *) name;-(void) sort;-(void) addCard: (AddressCard *) theCard;-(void) removeCard: (AddressCard *) theCard;-(int) entries;-(void) list;-(AddressCard *) lookup: (NSString *) theName;-(void) dealloc;@end#import "AddressBook.h"@implementation AddressBook@synthesize book, bookName;// set up the AddressBook’s name and an empty book-(id) initWithName: (NSString *) name{self = [super init];if (self) {bookName = [[NSStringalloc] initWithString: name];book = [[NSMutableArrayalloc] init];}return self;}-(void) sort{[book sortUsingSelector: @selector(compareNames:)];}-(void) addCard: (AddressCard *) theCard{[book addObject: theCard];}-(void) removeCard: (AddressCard *) theCard{[book removeObjectIdenticalTo: theCard];}-(int) entries{return [book count];}-(void) list{NSLog (@"======== Contents of: %@ =========", bookName);for ( AddressCard *theCard in book )NSLog (@"%-20s %-32s", [theCard.name UTF8String],[theCard.email UTF8String]);NSLog (@"==================================================");}// lookup address card by name — assumes an exact match-(AddressCard *) lookup: (NSString *) theName{for ( AddressCard *nextCard in book )if ( [[nextCard name] caseInsensitiveCompare: theName] == NSOrderedSame )return nextCard;return nil;}-(void) dealloc{[bookName release];[book release];[super dealloc];}-(void) encodeWithCoder: (NSCoder *) encoder{[encoder encodeObject:bookNameforKey:@"AddressBookBookName"];[encoder encodeObject:bookforKey: @"AddressBookBook"];}-(id) initWithCoder: (NSCoder *) decoder{bookName = [[decoder decodeObjectForKey: @"AddressBookBookName"] retain];book = [[decoder decodeObjectForKey: @"AddressBookBook"] retain];return self;}// Method for NSCopying protocol-(id) copyWithZone: (NSZone *) zone{AddressBook *newBook = [[self class] allocWithZone: zone]; [newBookinitWithName: bookName]; [newBooksetBook: book]; return newBook;}@end实现:
#import "AddressBook.h"#import <Foundation/NSAutoreleasePool.h>int main (intargc, char *argv[]){NSString *aName = @"Julia Kochan";NSString *aEmail = @"jewls337@axlc.com";NSString *bName = @"Tony Iannino";NSString *bEmail = @"tony.iannino@techfitness.com";NSString *cName = @"Stephen Kochan";NSString *cEmail = @"steve@steve_kochan.com";NSString *dName = @"Jamie Baker";NSString *dEmail = @"jbaker@hitmail.com";NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];AddressCard *card1 = [[AddressCardalloc] init];AddressCard *card2 = [[AddressCardalloc] init];AddressCard *card3 = [[AddressCardalloc] init];AddressCard *card4 = [[AddressCardalloc] init];AddressBook *myBook = [AddressBookalloc];// First set up four address cards[card1 setName: aNameandEmail: aEmail];[card2 setName: bNameandEmail: bEmail];[card3 setName: cNameandEmail: cEmail];[card4 setName: dNameandEmail: dEmail];myBook = [myBookinitWithName: @"Steve’s Address Book"];// Add some cards to the address book[myBookaddCard: card1];[myBookaddCard: card2];[myBookaddCard: card3];[myBookaddCard: card4];[myBook sort];if ([NSKeyedArchiverarchiveRootObject: myBooktoFile: @"addrbook.arch"] == NO)NSLog (@"archiving failed");[card1 release];[card2 release];[card3 release];[card4 release];[myBook release];[pool drain];return 0;}// Addresscard.h Interface File 对AddressBook解码#import "AddressBook.h"#import <Foundation/NSAutoreleasePool.h>int main (intargc, char *argv[]){AddressBook *myBook;NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];myBook = [NSKeyedUnarchiverunarchiveObjectWithFile: @"addrbook.arch"];[myBook list];[pool drain];return 0;}
@interface Foo: NSObject<NSCoding>{NSString *strVal;intintVal; float floatVal;}@property (copy, nonatomic) NSString *strVal;@property intintVal;@property float floatVal;@end@implementation Foo@synthesize strVal, intVal, floatVal;-(void) encodeWithCoder: (NSCoder *) encoder{ //对每个实例变量编码 归档对象的三个实例变量 [encoder encodeObject: strValforKey: @”FoostrVal”]; [encoder encodeInt: intVal forKey: @”FoointVal”]; [encoder encodeFloat: floatValforKey: @”FoofloatVal”];}-(id) initWithCoder: (NSCoder *) decoder{ //解码每个实例变量strVal = [[decoder decodeObjectForKey: @”FoostrVal”] retain];intVal = [decoder decodeIntForKey: @”FoointVal”];floatVal = [decoder decodeFloatForKey: @”FoofloatVal”]; return self;}@end
#import <Foundation/NSObject.h>#import <Foundation/NSString.h>#import <Foundation/NSKeyedArchiver.h>#import <Foundation/NSAutoreleasePool.h>#import “Foo.h” // Definition for our Foo classint main (intargc, char *argv[]){NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];Foo *myFoo1 = [[Fooalloc] init]; Foo *myFoo2;[myFoo1 setStrVal: @”This is the string”];[myFoo1 setIntVal: 12345];[myFoo1 setFloatVal: 98.6];[NSKeyedArchiverarchiveRootObject: myFoo1 toFile: @”foo.arch”];myFoo2 = [NSKeyedUnarchiverunarchiveObjectWithFile: @”foo.arch”];NSLog (@”%@\n%i\n%g”, [myFoo2 strVal], [myFoo2 intVal], [myFoo2 floatVal]);[myFoo1 release];[pool drain];return 0;}
结果:
//归档#import <Foundation/NSObject.h>#import <Foundation/NSAutoreleasePool.h>#import <Foundation/NSString.h>#import <Foundation/NSKeyedArchiver.h>#import <Foundation/NSCoder.h>#import <Foundation/NSData.h>#import "AddressBook.h"#import "Foo.h"int main (intargc, char *argv[]){NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];Foo *myFoo1 = [[Fooalloc] init];Foo *myFoo2;NSMutableData *dataArea;NSKeyedArchiver *archiver;AddressBook *myBook;// in myBook containing four address cards [myFoo1 setStrVal: @"This is the string"]; [myFoo1 setIntVal: 12345]; [myFoo1 setFloatVal: 98.6];// Set up a data area and connect it to an NSKeyedArchiver objectdataArea = [NSMutableData data];archiver = [[NSKeyedArchiveralloc]initForWritingWithMutableData: dataArea];// Now we can begin to archive objects [archiverencodeObject: myBookforKey: @"myaddrbook"]; [archiverencodeObject: myFoo1 forKey: @"myfoo1"]; [archiverfinishEncoding];// Write the archived data to a file if ( [dataAreawriteToFile: @"myArchive" atomically: YES] == NO)NSLog (@"Archiving failed!"); [archiver release]; [myFoo1 release]; [pool drain]; return 0;}
//解码#import <Foundation/NSObject.h>#import <Foundation/NSAutoreleasePool.h>#import <Foundation/NSString.h>#import <Foundation/NSKeyedArchiver.h>#import <Foundation/NSCoder.h>#import <Foundation/NSData.h>#import "AddressBook.h"#import "Foo.h"int main (intargc, char *argv[]){NSAutoreleasePool * pool = [[NSAutoreleasePoolalloc] init];NSData *dataArea;NSKeyedUnarchiver *unarchiver;Foo *myFoo1;AddressBook *myBook; // Read in the archive and connect an // NSKeyedUnarchiver object to itdataArea = [NSDatadataWithContentsOfFile: @"myArchive"];if (! dataArea) {NSLog (@"Can’t read back archive file! "); return (1);}unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData: dataArea];// Decode the objects we previously stored in the archivemyBook = [unarchiverdecodeObjectForKey: @"myaddrbook"];myFoo1 = [unarchiverdecodeObjectForKey: @"myfoo1"];[unarchiverfinishDecoding];[unarchiver release];// Verify that the restore was successful[myBook list];NSLog(@"%@\n%i\n%g", [myFoo1 strVal],[myFoo1 intVal], [myFoo1 floatVal]);[pool release];return 0;}
#import <Foundation/NSObject.h>#import <Foundation/NSAutoreleasePool.h>#import <Foundation/NSString.h>#import <Foundation/NSKeyedArchiver.h>#import <Foundation/NSArray.h>int main (intargc, char *argv[]){NSAutoreleasePool *pool = [[NSAutoreleasePoolalloc] init];NSData *data;NSMutableArray *dataArray = [NSMutableArrayarrayWithObjects: [NSMutableStringstringWithString: @"one"], [NSMutableStringstringWithString: @"two"], [NSMutableStringstringWithString: @"three"], nil ];NSMutableArray *dataArray2;NSMutableString *mStr; // Make a deep copy using the archiver data = [NSKeyedArchiverarchivedDataWithRootObject: dataArray]; dataArray2 = [NSKeyedUnarchiverunarchiveObjectWithData: data]; mStr = [dataArray2 objectAtIndex: 0]; [mStrappendString: @"ONE"];NSLog (@"dataArray: "); for ( NSString *elem in dataArray )NSLog ("%@", elem);NSLog (@"\ndataArray2: "); for ( NSString *elem in dataArray2 )NSLog ("%@", elem); [pool drain]; return 0;}
结果:
- ObjC学习11-复制对象与归档
- objc对象归档 序列化
- objc对象归档 序列化
- objc对象归档(序列化)
- Programming in Objective-C 学习笔记09——对象复制与归档
- OC视频笔记-对象的复制与归档
- 转载:objc与鸭子对象
- objc 复制
- 复制对象、对象归档和单例
- objc与鸭子对象(上)
- objc与鸭子对象(下)
- 利用objc runtime 和 KVC 对自定义对象归档解档
- 【IPHONE开发-OBJECTC入门学习】对象的归档和解归档
- Object-C 学习笔记(三十)--- 归档(3)---对象归档
- iOS开发之数据以及对象归档与解归档
- 48.复杂对象写入归档与反归档
- 使用归档来创建对象的深复制
- objective-C学习 自定义对象归档 archiver2
- Ubuntu(Linux)使用Eclipse搭建C/C++编译环境
- C++ 智能指针详解
- em = px / 字体默认值 (font-size默认16px)
- PHP网站被挂马防御战
- mysql set
- ObjC学习11-复制对象与归档
- Enum,Typedef 应用
- How to use Microsoft Unity to implement Ioc and AOP mechanism
- mount挂载qcow2镜像文件
- 未定义基类
- css渐变参数说明(webkit内核的safari、 Chrome, FF等)
- IAR 中修改存在的工程名
- C++拷贝构造函数(深拷贝,浅拷贝)
- 开机后台自动安装apk