Iphone 关于Objective-C中的复制属性

Iphone 关于Objective-C中的复制属性,iphone,objective-c,ios,cocoa-touch,nsstring,Iphone,Objective C,Ios,Cocoa Touch,Nsstring,我测试了这个示例代码 样本h { NSString *string1; NSString *string2; NSMutableString *string3; } @property (assign) IBOutlet NSWindow *window; @property (strong,nonatomic) NSString *string1; @property (copy,nonatomic) NSString *string2; @property (s

我测试了这个示例代码

样本h

 {

    NSString *string1;
    NSString *string2;
    NSMutableString *string3;
}

@property (assign) IBOutlet NSWindow *window;
@property (strong,nonatomic) NSString *string1;
@property (copy,nonatomic) NSString *string2;
@property (strong,nonatomic) NSMutableString *string3;

@end
样本m

#import "Sample.h"

@synthesize string1;
@synthesize string2;
@synthesize string3;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    string1 = [[NSString alloc] init];
    string2 = [[NSString alloc] init];
    string3 = [[NSMutableString alloc] initWithString:@"test"];
    string2 = string3;
    string1 = string3;
    [string3 appendString:@"test"];
    NSLog(@"%@",string1);
    NSLog(@"%@",string2);
    NSLog(@"%@",string3);

}

@end
结果是

2012-09-23 00:11:48.610 sample[13468:303] testtest
2012-09-23 00:11:48.611 sample[13468:303] testtest
2012-09-23 00:11:48.611 sample[13468:303] testtest
我认为string2应该是“test”,因为属性是copy。 但是string2是“testtest”

我想这就是结果

string2 is "test"
为什么??
请告诉我,我睡不好。

问题是,您没有访问属性,但是您正在立即操作备份实例变量。对于那些IVAR,
=
操作符不是特殊的,并且没有调用setter方法的效果,它只是一个常规指针赋值。所以当你写作的时候

string2 = string3;
string1 = string3
然后将指向
string3
的指针同时指定给
string1
string2
——无论您如何处理
string3
,它都会对其他两个变量有效,因为实际上,它们指向的是同一个字符串实例

你要做的是一个,声明你的属性为
copy
,而不是
strong
,第二个,写

self.string2 = string3;
self.string1 = string3
以便调用setter方法并实际制作字符串的独立副本

附言。通过使用

string1 = [[NSString alloc] init];
string2 = [[NSString alloc] init];
编写代码,然后将其他内容重新分配给这些变量,这就是内存泄漏

编辑:你很幸运,但你没有——通过使用ARC。使用旧的运行时,您可能会浪费用户RAM中宝贵的字节


但仍然如此。您不需要创建这些实例,也不需要直接
memcpy()
”将字符放入预先分配的内存中。在深入研究iOS开发之前,请阅读有关C指针的全面教程。

问题在于,您没有访问属性,而是立即操作备份实例变量。对于那些IVAR,
=
操作符不是特殊的,并且没有调用setter方法的效果,它只是一个常规指针赋值。所以当你写作的时候

string2 = string3;
string1 = string3
然后将指向
string3
的指针同时指定给
string1
string2
——无论您如何处理
string3
,它都会对其他两个变量有效,因为实际上,它们指向的是同一个字符串实例

你要做的是一个,声明你的属性为
copy
,而不是
strong
,第二个,写

self.string2 = string3;
self.string1 = string3
以便调用setter方法并实际制作字符串的独立副本

附言。通过使用

string1 = [[NSString alloc] init];
string2 = [[NSString alloc] init];
编写代码,然后将其他内容重新分配给这些变量,这就是内存泄漏

编辑:你很幸运,但你没有——通过使用ARC。使用旧的运行时,您可能会浪费用户RAM中宝贵的字节


但仍然如此。您不需要创建这些实例,也不需要直接
memcpy()
”将字符放入预先分配的内存中。在深入研究iOS开发之前,请阅读一篇关于C指针的全面教程。

我不知道为什么您会说
string2
属性上的setter语义是
copy
。您将其声明为
strong

NSString
指针字符串2设置为
NSMutableString
指针字符串3。然后继续修改string3指向的可变字符串。所以您应该期望string2能够反映这一点


顺便说一句,这就是为什么应该在具有可变对等对象的对象上使用
copy
setter语义的主要原因

我不知道您为什么说
string2
属性上的setter语义是
copy
。您将其声明为
strong

NSString
指针字符串2设置为
NSMutableString
指针字符串3。然后继续修改string3指向的可变字符串。所以您应该期望string2能够反映这一点


顺便说一句,这就是为什么应该在具有可变对等对象的对象上使用
copy
setter语义的主要原因

在代码或ivar属性中,您在何处看到任何
副本
?我只看到
strong
(与ARC之前的
retain
关键字相同),而没有看到
copy
。在代码或ivar属性中,您在哪里看到任何
copy
?我只看到
strong
(与ARC之前的
retain
关键字相同),而没有看到
copy
+1清楚地解释了直接操作IVAR和访问属性之间的区别。“你在泄漏内存”-他似乎在使用ARCthough@alanduncan啊,是的,很好。不过,我没有使用ARC,因此不确定重新分配是否会使多余创建的NSString实例失去refcount.carbonic acid-我认为LLVM会为您插入该版本以及下面的类似实例ARC@alanduncan谢谢,感谢你的评论,因为你知道我的真名D+1清楚地解释了直接操作IVAR和访问属性之间的区别。“你在泄漏内存”-看起来他在使用ARCthough@alanduncan啊,是的,很好。不过,我没有使用ARC,因此不确定重新分配是否会使多余创建的NSString实例失去refcount.carbonic acid-我认为LLVM会为您插入该版本以及下面的类似实例ARC@alanduncan谢谢,感谢你的评论,因为你知道我的真名D