弱属性无法使用ARC归零

编程入门 行业动态 更新时间:2024-10-18 01:30:40
本文介绍了弱属性无法使用ARC归零的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

对于持有弱引用的对象,我有以下简单代码:

I have the following simple code for an object that holds a weak reference:

//接口

@interface GMWeakRefObj : NSObject @property (weak) id object; @end

//实现

@implementation GMWeakRefObj @synthesize object; @end

当我运行以下测试代码时,它在第二个断言上失败:

When I run the following test code it fails on the second assert:

NSData* d = [[NSData alloc] init]; GMWeakRefObj* weakRef = [[GMWeakRefObj alloc] init]; weakRef.object = d; NSAssert(weakRef.object != nil, @"Reference wasn't assigned"); d = nil; NSAssert(weakRef.object == nil, @"Reference wasn't zeroed"); // <-- FAIL

ARC弱引用不是应该归零吗?如果是这样,我在做什么错了?

Aren't ARC weak references supposed to be zeroing? And if so what am I doing wrong?

推荐答案

为d尝试一些自定义类而不是NSData,例如MyData.在其中实现dealloc方法并在其中设置断点.您会看到,dealloc在最后一个NSAssert之后由自动释放池 调用.仅在该周之后,引用将变为nil.

Try some custom class class instead of NSData for d, e.g. MyData. Implement dealloc method in it and set breakpoint in it. You will see, that dealloc is called by autorelease pool after the last NSAssert. Only after that week reference will become nil.

添加: 看来我必须扩展我的答案才能清楚说明为什么它会那样工作. 首先,让我们看看您的示例(来自评论):

ADD: Looks like I have to extend my answer to make it clear, why it works that way. First, lets look at your example (from comments):

NSData* data = [[NSData alloc] init]; __weak NSData* weakRef = data; data = nil; NSAssert(weakRef == nil, @"Failed to zero");

它按预期方式工作,data = nil之后,weakRef变为nil.下一个示例也适用:

It works as expected, weakRef become nil after data = nil. The next example works too:

NSData* data = [[NSData alloc] init]; __weak NSData* weakRef = data; NSLog(@"%@", data); data = nil; NSAssert(weakRef == nil, @"Failed to zero");

但是最后一个示例不起作用:

But the last example doesn't work:

NSData* data = [[NSData alloc] init]; __weak NSData* weakRef = data; NSLog(@"%@", weakRef); data = nil; NSAssert(weakRef == nil, @"Failed to zero");

唯一的区别是我们使用弱引用来输出日志.为什么?

The only difference is that we use weak reference to output log. Why?

(其他答案可能是错误的:))

想象您NSLog(或我们在data = nil之前调用的任何其他函数/选择器)依赖于它的参数不是nil.例如,它具有"if(arg == nil)return;".一开始.

Imaging that you NSLog (or any other function/selector we call before data = nil) rely on it's argument not to be nil. For example, it has "if (arg == nil) return;" at the very beginning.

在多线程环境中,弱引用可以在 if之后成为nil .

In multithreaded environment weak reference can become nil after if.

因此正确编写的函数应如下所示:

So properly written function should look like:

// ... T* local_arg = arg; // NOTE: it is strong! if (local_arg == nil) return; // work with local_arg here, not with arg // ...

但是通常我们不想在任何地方都这样做-这将是丑陋的.因此,我们要确保论点不会在中间的某个地方消失.编译器通过自动释放弱引用为我们做到这一点.

But usually we don't want to do it everywhere -- it will be ugly. So we want to be sure that arguments will not disappear somewhere in the middle. Compiler does it for us by autoreleasing weak reference.

因此,应该清楚为什么GMWeakRefObj测试用例不起作用-在调用setObject setter之前会自动释放weakRef.

So, it should be clear how, why your GMWeakRefObj test case doesn't work -- weakRef is autoreleased before calling setObject setter.

更多推荐

弱属性无法使用ARC归零

本文发布于:2023-11-13 02:14:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1583136.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:属性   ARC

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!