Iphone 关于Objective-C中的复制属性
我测试了这个示例代码 样本hIphone 关于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
{
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