2012年5月27日 星期日

Copy and mutableCopy

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009) 

int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray    *dataArray = [NSMutableArray arrayWithObjects:
@ ” one ” , @ ” two ” , @ ” three ” , @ ” four ” , nil];
NSMutableArray    *dataArray2;

// simple assignment
dataArray2 = dataArray;
[dataArray2 removeObjectAtIndex: 0]; //移除第一筆資料,看對dataArray的影響
NSLog (@ ” dataArray: “ );
for ( NSString *elem in dataArray )
NSLog (@ ” %@ ” , elem);
NSLog (@ ” dataArray2: “ );
for ( NSString *elem in dataArray2 )
NSLog (@ ” %@ ” , elem);

// try a Copy, then remove the first element from the copy
dataArray2 = [dataArray mutableCopy]; //產生兩個不同的記憶區塊
[dataArray2 removeObjectAtIndex: 0]; //移除第一筆資料,看對dataArray的影響
NSLog (@ ” dataArray: “ );
for ( NSString *elem in dataArray )
NSLog (@ ” %@ ” , elem); 
NSLog (@ ” dataArray2: “ );
for ( NSString *elem in dataArray2 )
NSLog (@ ” %@ ” , elem);

[dataArray2 release];  //只需對dataArray2做release動作就可以了
[pool drain];
return 0;
}

dataArray:
two
three
four
dataArray2:
two
three
four

dataArray:
two     //資料不受影響,因為dataArray區已經與dataArray2區不同了
three
four
dataArray2:
three
four

Another Example for  mutable strings

int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray    *dataArray = [NSMutableArray arrayWithObjects:
[NSMutableString stringWithString: @ ” one ” ], //裡面也是NSMutableString
[NSMutableString stringWithString: @ ” two ” ],
[NSMutableString stringWithString: @ ” three ” ],
nil
];
NSMutableArray    *dataArray2;
NSMutableString   *mStr;

NSLog (@ ” dataArray: “ );
for ( NSString *elem in dataArray )
NSLog (@ ” %@ ” , elem);

// make a copy, then change one of the strings
dataArray2 = [dataArray mutableCopy]; //  要產生兩個記憶區塊,但只針對dataArray裡的point參考區,有作複製的動作,對次一級的array資料區並沒有複製 
//因此dataArray及dataArray2雖有兩個不同point區的記憶區塊,但其兩邊的point只是指向相同的資料記憶區塊

mStr = [dataArray objectAtIndex: 0]; //針對array[0]將入"ONE"
[mStr appendString: @ ” ONE ” ];

NSLog (@ ” dataArray: “ );
for ( NSString *elem in dataArray )
NSLog (@ ” %@ ” , elem);

NSLog (@ ” dataArray2: “ );
for ( NSString *elem in dataArray2 )
NSLog (@ ” %@ ” , elem);

[dataArray2 release];
[pool drain];
return 0;
}

dataArray:
one
two
three

dataArray:
oneONE
two
three

dataArray2:
oneONE
two
three

以上所做的都只是shallow Copy,要將整個array內部含括所有Point指向的區塊的所有資料都備份,則需要Deep Copy 

Shallow and deep copies of an object 

 

Making a shallow copy
NSArray *shallowCopyArray=[someArray copyWithZone:nil];
 
NSDictionary *shallowCopyDict=[[NSDictionary alloc] initWithDictionary: someDictionary copyItems: NO];

Making a deep copy
NSArray *deepCopyArray=[[NSArray alloc] initWithArray: someArray copyItems: YES];
  

另一個真正的Deep Copy,使用壓縮解壓縮的方式, NSCoding protocol.

NSData *buffer;

buffer = [NSKeyedArchiver archivedDataWithRootObject: myArray1];
myArray2 = [NSKeyedUnarchiver unarchiveObjectWithData: buffer];



 

沒有留言: