【问题标题】:About copy property in Objective-C关于 Objective-C 中的复制属性
【发布时间】:2012-09-22 15:59:51
【问题描述】:

我测试了这个示例代码。

示例.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 应该是“测试”,因为该属性是副本。 但是 string2 是“testtest”。

string2 = [string3 copy];

这是我认为的结果。

string2 is "test"

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

【问题讨论】:

  • 您在代码或 ivar 属性中的何处看到任何 copy?我只看到strong(与ARC之前的retain关键字相同),而不是copy

标签: iphone objective-c ios cocoa-touch nsstring


【解决方案1】:

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

string2 = string3;
string1 = string3

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

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

self.string2 = string3;
self.string1 = string3

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

P。 s。通过使用您的

创建两个空的 NSString 实例
string1 = [[NSString alloc] init];
string2 = [[NSString alloc] init];

代码,然后将其他内容重新分配给这些变量,您正在泄漏内存。

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

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

【讨论】:

  • +1 用于清楚地解释直接操作 ivars 和访问属性之间的区别。
  • “你正在泄漏内存” - 不过他似乎在使用 ARC
  • @alanduncan 啊,是的,很好的发现。不过我没有使用 ARC,所以不确定重新分配是否会使多余创建的 NSString 实例失去引用计数。
  • 碳酸 - 我认为 LLVM 会在 ARC 下的那个和类似情况下为你插入版本
  • @alanduncan 感谢,并为您知道我的真实姓名的评论 +1。 :D
【解决方案2】:

我不确定您为什么说 string2 属性上的 setter 语义是 copy。你声明了它strong

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

顺便说一句,这是您应该在具有可变对应物的对象上使用copy setter 语义的主要原因。

【讨论】:

    猜你喜欢
    • 2012-10-07
    • 1970-01-01
    • 2011-08-08
    • 2015-08-14
    • 2012-08-18
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-12-15
    相关资源
    最近更新 更多