弱与不安全之间的差异

时间:2022-09-02 11:12:04

So I had a project that supported iOS 4, so all my IBOutlets were __unsafe_unretained even IBOutlets that were in the nib but outside the controllers main view (Separate View in the same nib) and all worked great.

所以我有一个支持iOS 4的项目,所以我的所有IBOutlet都是__unsafe_unretained甚至是在nib中但在控制器主视图之外的IBOutlets(在同一个nib中的Separate View)并且都很好用。

So the time has come and now the client wants to support only iOS 5 so our team changed all the __unsafe_unretained IBOutlets for __weak IBOutlets but now the IBOutlets that are not inside the main view are set to nil (except in viewdidload) so we are unable to add them later.

所以时机已到,现在客户只想支持iOS 5,所以我们的团队为__weak IBOutlets改变了所有__unsafe_unretained IBOutlets,但是现在不在主视图中的IBOutlets被设置为nil(在viewdidload中除外)所以我们无法稍后添加它们。

If I think about it, it makes sense because if no view (main view) is retaining those IBOutlets they should be deallocated and zeroed (I don't know if that is the correct word), so the solution is to remove the __weak from those IBOutlets

如果我考虑一下,这是有道理的,因为如果没有视图(主视图)保留那些IBOutlets它们应该被释放并归零(我不知道这是否是正确的单词),所以解决方案是从中删除__weak那些IBOutlets

But what doesn't make sense to me is Why the different behavior between unsafe_unretained and weak, in my head the unsafe_unretained ones should be deallocated and when the app tries to access them, they should point to an invalid reference and then the app should crash.

但对我来说没有意义的是为什么unsafe_unretained和weak之间的不同行为,在我脑海中应该释放unsafe_unretained,并且当应用程序试图访问它们时,它们应该指向无效的引用,然后应用程序应该崩溃。

I thought that unsafe__unretained was the same as weak but without the zeroing.

我认为不安全的不安全与弱者相同但没有归零。

Am I missing something here?

我在这里错过了什么吗?

Thanks.

3 个解决方案

#1


5  

I thought that unsafe__unretained was the same as weak but without the zeroing.

我认为不安全的不安全与弱者相同但没有归零。

It is, yes.

是的,是的。

When Cocoa loads the nib, it creates all the objects autoreleased, so they are still there when viewDidLoad is invoked. However, the autorelease pool has a lifetime that ends when control returns to the run loop. At this point all the objects that aren't owned by anything will go away so any weak outlets will be zeroed at that point.

当Cocoa加载nib时,它会创建所有自动释放的对象,因此在调用viewDidLoad时它们仍然存在。但是,自动释放池的生命周期在控制返回到运行循环时结束。此时,所有不属于任何东西的物体都将消失,因此任何弱的出口都将在此时归零。

For most outlets, this is not a problem because objects in the NIB are already generally owned by something anyway. So, for instance, a button in a view is owned by its parent view. Having strong outlets that point to that button are therefore overkill or worse might result in a retain cycle.

对于大多数网点来说,这不是问题,因为NIB中的对象通常已经被某些东西所拥有。因此,例如,视图中的按钮由其父视图拥有。因此,具有指向该按钮的强大出口是过度的或更糟的可能导致保留周期。

Top level objects obviously don't have a parent view to own them so they need to be owned by something else e.g. a controller or "File's Owner". If you are finding stuff disappears, you need to create a strong IBOutlet for it in File's owner.

*对象显然没有父视图来拥有它们,因此它们需要由其他东西拥有,例如控制器或“文件所有者”。如果你发现东西消失了,你需要在File的所有者中为它创建一个强大的IBOutlet。

For more detail, see Apple's docs.

有关更多详细信息,请参阅Apple的文档。

#2


1  

For future searchers who come across this question, I think CRD's * answer to a similar question may explain. Even though the object has been deallocated, the memory that's referenced by the unsafe unretained pointer (which contains the actual object data) is not necessarily zeroed, so things may appear to behave properly until that memory is actually reused/modified/zeroed.

对于遇到此问题的未来搜索者,我认为CRD的*对类似问题的回答可以解释。即使对象已被释放,由不安全的未保留指针(包含实际对象数据)引用的内存也不一定归零,因此在实际重用/修改/归零该内存之前,事物可能看起来行为正常。

#3


0  

You are correct, the app will crash when trying to access deallocated objects through your stale __unsafe_unretained references.

你是对的,当试图通过陈旧的__unsafe_unretained引用访问解除分配的对象时,应用程序将崩溃。

The reason it doesn't is very likely because the objects are being referenced by some other part of your app with strong references.

之所以不是这样的原因很可能是因为应用程序的某些其他部分正在引用具有强引用的对象。

Try running with zombies enabled, that should cause an immediate crash when dereferencing the presumedly stale pointers.

尝试在启用僵尸的情况下运行,这会在取消引用假定过时的指针时立即导致崩溃。

#1


5  

I thought that unsafe__unretained was the same as weak but without the zeroing.

我认为不安全的不安全与弱者相同但没有归零。

It is, yes.

是的,是的。

When Cocoa loads the nib, it creates all the objects autoreleased, so they are still there when viewDidLoad is invoked. However, the autorelease pool has a lifetime that ends when control returns to the run loop. At this point all the objects that aren't owned by anything will go away so any weak outlets will be zeroed at that point.

当Cocoa加载nib时,它会创建所有自动释放的对象,因此在调用viewDidLoad时它们仍然存在。但是,自动释放池的生命周期在控制返回到运行循环时结束。此时,所有不属于任何东西的物体都将消失,因此任何弱的出口都将在此时归零。

For most outlets, this is not a problem because objects in the NIB are already generally owned by something anyway. So, for instance, a button in a view is owned by its parent view. Having strong outlets that point to that button are therefore overkill or worse might result in a retain cycle.

对于大多数网点来说,这不是问题,因为NIB中的对象通常已经被某些东西所拥有。因此,例如,视图中的按钮由其父视图拥有。因此,具有指向该按钮的强大出口是过度的或更糟的可能导致保留周期。

Top level objects obviously don't have a parent view to own them so they need to be owned by something else e.g. a controller or "File's Owner". If you are finding stuff disappears, you need to create a strong IBOutlet for it in File's owner.

*对象显然没有父视图来拥有它们,因此它们需要由其他东西拥有,例如控制器或“文件所有者”。如果你发现东西消失了,你需要在File的所有者中为它创建一个强大的IBOutlet。

For more detail, see Apple's docs.

有关更多详细信息,请参阅Apple的文档。

#2


1  

For future searchers who come across this question, I think CRD's * answer to a similar question may explain. Even though the object has been deallocated, the memory that's referenced by the unsafe unretained pointer (which contains the actual object data) is not necessarily zeroed, so things may appear to behave properly until that memory is actually reused/modified/zeroed.

对于遇到此问题的未来搜索者,我认为CRD的*对类似问题的回答可以解释。即使对象已被释放,由不安全的未保留指针(包含实际对象数据)引用的内存也不一定归零,因此在实际重用/修改/归零该内存之前,事物可能看起来行为正常。

#3


0  

You are correct, the app will crash when trying to access deallocated objects through your stale __unsafe_unretained references.

你是对的,当试图通过陈旧的__unsafe_unretained引用访问解除分配的对象时,应用程序将崩溃。

The reason it doesn't is very likely because the objects are being referenced by some other part of your app with strong references.

之所以不是这样的原因很可能是因为应用程序的某些其他部分正在引用具有强引用的对象。

Try running with zombies enabled, that should cause an immediate crash when dereferencing the presumedly stale pointers.

尝试在启用僵尸的情况下运行,这会在取消引用假定过时的指针时立即导致崩溃。