关于Objective-C中的copy属性

Mas*_*eta 0 iphone cocoa-touch objective-c nsstring ios

我测试了这个示例代码.

Sample.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
Run Code Online (Sandbox Code Playgroud)

Sample.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
Run Code Online (Sandbox Code Playgroud)

结果是

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
Run Code Online (Sandbox Code Playgroud)

我认为string2应该是"test",因为属性是copy.但是string2是"testtest".

string2 = [string3 copy];
Run Code Online (Sandbox Code Playgroud)

这是我想的结果.

string2 is "test"
Run Code Online (Sandbox Code Playgroud)

为什么?请告诉我,我睡不好觉.

小智 5

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

string2 = string3;
string1 = string3
Run Code Online (Sandbox Code Playgroud)

然后你将指针分配string3给两者string1string2- 无论你做什么string3,它对其他两个变量都有效,因为实际上,它们指向同一个字符串实例.

你需要做的就是一个,声明你的属性copy而不是strong两个,写

self.string2 = string3;
self.string1 = string3
Run Code Online (Sandbox Code Playgroud)

为了调用setter方法并实际制作字符串的独立副本.

P. s.通过使用您的.创建两个空的NSString实例

string1 = [[NSString alloc] init];
string2 = [[NSString alloc] init];
Run Code Online (Sandbox Code Playgroud)

代码,然后将其他东西重新分配给那些变量,你就是在泄漏内存.

编辑:你很幸运,你没有 - 使用ARC.使用旧的运行时,您将浪费用户RAM的宝贵字节.

但仍然.您不需要创建这些实例 - 您不是直接memcpy()将字符放入预分配的内存中.在深入研究iOS开发之前,请阅读关于C指针的综合教程.

  • 碳酸 - 我认为LLVM会在ARC中为您和类似的实例插入发行版 (2认同)