首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >电弧与__unsafe_unretained

电弧与__unsafe_unretained
EN

Stack Overflow用户
提问于 2012-11-20 16:11:55
回答 5查看 2.5K关注 0票数 2

我认为我对ARC和选择适当的终身限定符(__strong__weak__unsafe_unretained__autoreleasing)的正确用例有很好的理解。然而,在我的测试中,我发现了一个对我来说没有意义的例子。

据我所知,__weak__unsafe_unretained都没有添加保留计数。因此,如果没有指向该对象的其他__strong指针,则该对象立即被释放(不可变字符串是此规则的一个例外)。这个过程中唯一的区别是__weak指针被设置为零,而__unsafe_unretained指针被单独保留。

如果我创建一个指向简单的自定义对象的__weak指针(由一个NSString属性组成),则在尝试访问属性时会看到预期的(null)值:

代码语言:javascript
复制
Test * __weak myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: (null)

同样,由于所产生的悬空指针,我希望__unsafe_unretained生存期限定符会导致崩溃。但是,在下一个测试中,我看到了实际值:

代码语言:javascript
复制
Test * __unsafe_unretained myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: Hi!

为什么__unsafe_unretained对象没有被释放?

编辑:对象正在被解除分配.如果我试图用NSLog(@"%@", myTest);替换第2-3行,应用程序就会崩溃(并且在第一行之后将立即调用Test中覆盖的dealloc )。我知道,即使在__unsafe_unretained中,不可变字符串仍然可用,指向NSString的直接指针也能工作。我感到惊讶的是,我可以在一个已释放的对象(第2行)上设置一个属性,并且以后可以从指向它所属的已分配对象的指针中取消它的引用(第3行)!如果有人能解释的话,它肯定会回答我的问题。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-11-21 00:21:44

我感到惊讶的是,我可以在一个已释放的对象(第2行)上设置一个属性,并且以后可以从指向它所属的已分配对象的指针中取消它的引用(第3行)!如果有人能解释的话,它肯定会回答我的问题。

当对象被解除分配时,它不会被归零。由于您有指向已分配对象的指针,并且属性值存储在指向该指针的某个偏移量处,因此在取消分配后存储和检索该属性值是可能的,因此也很有可能由于某种原因所有的东西都会爆炸。

如果您的代码非常脆弱,尝试使用“显示调试过程中的反汇编”进行调试,然后逐步执行,您可能会遇到访问冲突,或者删除Xcode本身.

在C、Objective、C++或任何一个家庭中发生奇怪的事情,您不应该感到惊讶;相反,您应该为很少发生的奇怪事情而感到惊讶!

票数 3
EN

Stack Overflow用户

发布于 2012-11-20 16:57:36

因为objc中的常量字符串是指向堆地址的常量指针,并且该地址仍然有效。

评论后编辑的

也许是因为测试对象地址上的内存还没有被覆盖,并且仍然包含该对象?推测..。

票数 2
EN

Stack Overflow用户

发布于 2012-11-20 17:11:54

您可以通过实现Test-dealloc方法和添加一些简单的日志记录来查看何时解除它的分配。

但是,即使测试立即被取消分配,它在RAM中占用的内存在调用myVal时也可能保持不变。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13477318

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档