在Objective-C裡,很多類別常常有唯讀版與可變版,譬如NSString與NSMutableString、NSArray與NSMutableArray、NSDictionary與NSMutableDictionary,一般來說,唯讀版的物件建立之後就不能改變,可變版的物件建立後,可以隨心所欲地進行修改。
一旦建立出NSString物件,NSString類別並沒有提供任何方法讓我們修改其中的字串,但要小心,裡頭的字串還是有可能會改變的,以底下範例說明。
假設有個Person類別,有兩個屬性name(名字)與address(住址)。其中name屬性使用retain,address使用copy,也就是說,當你指定一個NSString物件給name時,它只會記住該物件指標並增加參考計數,而指定一個NSString物件給address時,它會傳送copy訊息給該物件,得到一份拷貝。
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
NSString *name;
NSString *address;
}
@property (nonatomic, retain) NSString *name;
@property (nonatomic, copy) NSString *address;
@end
// Person.m
#import "Person.h"
@implementation Person
@synthesize name;
@synthesize address;
-(NSString *)description
{
return [NSString stringWithFormat:@"name(%@), address(%@)", name, address];
}
@end
// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableString *sname = [NSMutableString stringWithString:@"Amanda"];
NSMutableString *aname = [NSMutableString stringWithString:@"Taiwan"];
Person *person = [[Person alloc] init];
person.name = sname;
person.address = aname;
NSLog(@"1: person=%@", person);
[sname appendString:@"XXX"];
[aname appendString:@"YYY"];
NSLog(@"2: person=%@", person);
[person release];
[pool release];
return 0;
}
首先建立兩個NSMutableString物件sname與aname,分別指定給person物件的name與address,然後印出person物件。接下來以NSMutableString介面修改sname與aname,然後再印出person物件,你會發現,person的name變了,address沒變。
程式輸出如下:
2012-04-14 23:01:47.603 TestNSString[24655:903] 1: person=name(Amanda), address(Taiwan)
2012-04-14 23:01:47.606 TestNSString[24655:903] 2: person=name(AmandaXXX), address(Taiwan)
結論,不要以為的物件的類別為NSString就不會改變,若要確保不變,屬性可使用copy宣告。
No comments:
Post a Comment