ios上的assign属性发生了什么

时间:2014-06-29 11:18:17

标签: ios properties assign

我在头文件中声明了两个属性: @property(strong)NSString *p1; @property(assign)NSString *p4; 现在在实现文件上,我写了两个方法来测试assign属性:

- (void)testAssign {
    NSString *rawString = @"Hello, ";
    NSString *resultString = [rawString stringByAppendingString:@"World"];
    self.p4 = resultString;
    resultString = nil;
    (@"My group is %@", self.p4);

 }

在这个场景中会出错。

但是当代码如下所示时,这样做很好:

- (void)testString {
    NSString *rawString = @"Hello, ";
    NSString *resultString = [rawString stringByAppendingString:@"World"];
    self.p4 = resultString;
    self.p1 = resultString;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
    resultString = nil;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
    self.p1 = nil;
    NSLog(@"now result is %@, %@", self.p4, self.p1);
 }

结果是:

2014-06-29 19:10:55.798 TestDemo[20853:303] now result is Hello, World, Hello, World
2014-06-29 19:10:55.798 TestDemo[20853:303] now result is Hello, World, Hello, World
2014-06-29 19:10:55.799 TestDemo[20853:303] now result is Hello, World, (null)

第二个片段发生了什么?为什么没有错误?

1 个答案:

答案 0 :(得分:2)

由于使用了assign属性并释放了它指向的对象,因此您在第一个代码段中收到了访问冲突。

你不会在第二个片段中获得一个,即使它应该有同样的问题 - 局部变量引用和强属性引用都是nilled,这应该留下一个无效的指针。

我怀疑这只是与编译器优化和时序有关。如果我单步进入调试器,两个片段都可以正常工作,表明单步过程也在改变。

在第二种情况下,如果您继续访问p4,则会看到最终崩溃,我通过在我的应用代理didFinishLaunching中调用您的代码确认,然后从{{1}访问self.p4 }}。启用Zombies使其更加清晰 - "消息被发送到解除分配的实例"在这两种情况下。

优先选择ARC willResignActive,因为这会将“无效”引用替换为“

另见 - Objective-C ARC: strong vs retain and weak vs assign