NSDictionary 中的弱对象?

Posted

技术标签:

【中文标题】NSDictionary 中的弱对象?【英文标题】:Weak object in an NSDictionary? 【发布时间】:2012-01-05 19:46:14 【问题描述】:

我想在NSDictionary 中存储一个对对象的归零弱引用。这是对父 NSDictionary 的引用,因此我无需搜索即可爬回大型结构。

我不能在这里使用__weak;即使我的本地引用很弱,NSDictionary 也会存储对被弱引用的对象的强引用。当然,NSDictionary 不能有 nil 对象。

我使用的是 ios,而不是 Mac,所以NSHashTable 不可用。我只希望一个对象是弱的;其余的应该仍然很强大。

(我将发布我的答案,所以如果没有更好的答案,我会标记为已接受。但我希望有人有更好的答案。)

【问题讨论】:

我创建了this 作为字典,将对象存储为有效地将弱引用归零。它可以被修改(和清理)以满足您的目的。 【参考方案1】:

在 iOS 6+ 中,您可以使用 NSMapTable 并选择您希望对象和/或键是弱还是强。

【讨论】:

显然是今天和未来的最佳答案。谢谢。 NSMapTable 的行为可能与预期不同:cocoamine.net/blog/2013/12/13/… NSMapTable 将完成这项工作。但仍然对valueWithNonretainedObject 的工作原理感到好奇?它拥有一个__weak 引用或__unsafe_unretained 一个。 @Timo 说 it works like __unsafe_unretained 。对吗? 这很容易测试。创建一个自动释放池。将键的值设置为您的对象。 “摧毁”你的对象。然后在自动释放池之后检查键的值 @Nickolas nsmaptable 不支持您提出的选项!【参考方案2】:

我决定用一个成员定义一个“容器”类,如下所示:

@interface Parent : NSObject
@property (nonatomic, weak) id parent;
@end

@implementation Parent

@synthesize parent = _parent;

- (id)initWithParent: (id)parent;

    if (( self = [super init] )) 
        _parent = parent;
    
    return self;

@end

并使用它:

id parentRef = [[Parent alloc] initWithParent: parent];
[newElement setObject: parentRef forKey: ParentKey];

我认为这对我有用,但似乎 疯狂 没有更好的方法内置到 Foundation 中。

【讨论】:

听起来对我来说是唯一的解决方案——我也会这样做。或者NSValue,但这不会归零。 我也遇到了同样的问题,我也想到了一个容器,我仍然没有尝试过,但我正在尝试做一些接近你对块 id __weak weakObject=strongObject; [optionDict setValue:[NSValue valueWithNonretainedObject:tmpObject] forKey:key]; 所做的事情仍然需要弄清楚它是否有效。 旧评论,但我会为新访客添加此评论。安德里亚所说的行不通,无论如何字典都会保留该对象。【参考方案3】:

有一种内置方式;只需使用:

[array addObject:[NSValue valueWithNonretainedObject:object]];

然后要稍后访问该对象,请使用:

id object = [[array objectAtIndex:i] nonretainedObjectValue];

如果自添加后该值已被释放,则“object”在 iOS 4.x 下将是无效指针,并且(我假设)在启用 ARC 的 5.x 下将为零。

编辑:我的假设是错误的 - 在 ARC 下它并不弱(见下面的讨论)。

【讨论】:

悬空指针永远不应该被访问,因为你的对象在那一刻濒临死亡。所以在这里访问父级应该是一个错误,在这种情况下,它不会被 niling 隐藏起来。 @Eiko,你错了。这是观察者模式的常见情况。

以上是关于NSDictionary 中的弱对象?的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的弱引用 WeakReference

从python中的弱引用代理获取常规引用

Objective-C 中的弱键字典

如何将变量与 NSArray 中的 NSDictionary 中的对象进行比较?

如何在 NSUserDefaults 中绑定 NSDictionary 中的对象?

调用 NSDictionary 中的所有键包含 JSON 对象时出错