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

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

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

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

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

【问题讨论】:

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

标签: ios nsdictionary automatic-ref-counting weak-references


【解决方案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,你错了。这是观察者模式的常见情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2011-08-16
  • 1970-01-01
  • 2011-12-25
相关资源
最近更新 更多