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
encode Object:forKey:和decode ObjectforKey:编码和解
//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 class
int 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 object
dataArea = [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 it
dataArea = [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 archive
myBook = [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;
}
结果:
