ARC和__unsafe_unretained [英] ARC and __unsafe_unretained

查看:62
本文介绍了ARC和__unsafe_unretained的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为我对ARC以及用于选择适当的生命周期限定符(__strong__weak__unsafe_unretained__autoreleasing)的正确用例有很好的理解.但是,在测试中,我发现了一个对我来说没有意义的示例.

I think I have a pretty good understanding of ARC and the proper use cases for selecting an appropriate lifetime qualifiers (__strong, __weak, __unsafe_unretained, and __autoreleasing). However, in my testing, I've found one example that doesn't make sense to me.

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

As I understand it, both __weak and __unsafe_unretained do not add a retain count. Therefore, if there are no other __strong pointers to the object, it is instantly deallocated (with immutable strings being an exception to this rule). The only difference in this process is that __weak pointers are set to nil, and __unsafe_unretained pointers are left alone.

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

If I create a __weak pointer to a simple, custom object (composed of one NSString property), I see the expected (null) value when trying to access a property:

Test * __weak myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: (null)

类似地,由于生成的悬空指针,我希望__unsafe_unretained生存期限定符会导致崩溃.但是,事实并非如此.在下一个测试中,我看到了实际值:

Similarly, I would expect the __unsafe_unretained lifetime qualifier to cause a crash, due to the resulting dangling pointer. However, it doesn't. In this next test, I see the actual value:

Test * __unsafe_unretained myTest = [[Test alloc] init];
myTest.myVal = @"Hi!";
NSLog(@"Value: %@", myTest.myVal); // Prints Value: Hi!

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

Why doesn't the __unsafe_unretained object become deallocated?

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

: The object is being deallocated... if I try to substitute lines 2 - 3 with NSLog(@"%@", myTest); the app crashes (and an overridden dealloc in Test is being called immediately after the first line). I know that immutable strings will continue to be available even with __unsafe_unretained, and that a direct pointer to the NSString would work. I am just surprised that I could set a property on a deallocated object (line 2), and that it could later be dereferenced from a pointer to the deallocated object it belonged to (line 3)! If anyone could explain that, it would definitely answer my question.

推荐答案

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

I am just surprised that I could set a property on a deallocated object (line 2), and that it could later be dereferenced from a pointer to the deallocated object it belonged to (line 3)! If anyone could explain that, it would definitely answer my question.

当对象被释放时,它不会被清零.由于您有一个指向已释放对象的指针,并且属性值存储在该指针的某个偏移处,因此可能在释放后将成功存储和检索该属性值,因此很可能所有内容会由于某种原因而爆炸.

When the object is deallocated it is not zeroed. As you have a pointer to the deallocated object and the property value is stored at some offset to that pointer it is possible that storing and retrieving that property value will succeed after deallocation, it is also quite possible that everything will blow up for some reason or other.

您的代码工作非常脆弱,请尝试使用调试时显示反汇编"进行调试并逐步执行,您可能会遇到访问冲突,或者删除Xcode本身...

That your code works is quite fragile, try debugging it with "Show Disassembly While Debugging" and stepping through, you'll probably hit an access violation, or take down Xcode itself...

对于C,Objective-C,C ++或任何一个家族中发生的奇怪事情,您永远不会感到惊讶.相反,请为如此少见的奇怪事情保留您的惊喜!

You should never be surprised that strange things happen in C, Objective-C, C++ or any of the family; instead reserve your surprise for so few strange things happening!

这篇关于ARC和__unsafe_unretained的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆