gpt4 book ai didi

objective-c - 弱属性不使用 ARC 归零

转载 作者:行者123 更新时间:2023-12-04 05:59:30 26 4
gpt4 key购买 nike

我有一个包含弱引用的对象的以下简单代码:

//界面

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

//执行
@implementation GMWeakRefObj 
@synthesize object;
@end

当我运行以下测试代码时,它在第二个断言时失败:
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 弱引用不应该归零吗?如果是这样,我做错了什么?

最佳答案

尝试一些自定义类而不是 NSDatad ,例如MyData .实现 dealloc方法并在其中设置断点。你会看到,dealloc在最后一个 NSAssert 之后由自动释放池调用.只有在那一周之后引用才会变成nil .

添加:
看起来我必须扩展我的答案以明确说明为什么它会这样工作。
首先,让我们看一下您的示例(来自评论):

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

它按预期工作, weakRef成为 nil之后 data = nil .下一个示例也适用:
NSData* data = [[NSData alloc] init];
__weak NSData* weakRef = data;
NSLog(@"%@", data);
data = nil;
NSAssert(weakRef == nil, @"Failed to zero");

但最后一个例子不起作用:
NSData* data = [[NSData alloc] init];
__weak NSData* weakRef = data;
NSLog(@"%@", weakRef);
data = nil;
NSAssert(weakRef == nil, @"Failed to zero");

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

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

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

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

所以正确编写的函数应该是这样的:
  // ...
T* local_arg = arg; // NOTE: it is strong!
if (local_arg == nil)
return;
// work with local_arg here, not with arg
// ...

但通常我们不想在任何地方都这样做——它会很丑。所以我们要确保参数不会在中间的某个地方消失。编译器通过自动释放弱引用来为我们做这件事。

所以,应该清楚如何,为什么你的 GMWeakRefObj测试用例不起作用 -- weakRef在调用之前自动释放 setObject二传手。

关于objective-c - 弱属性不使用 ARC 归零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9096008/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com