【问题标题】:Need assistance regarding memory management需要有关内存管理的帮助
【发布时间】:2018-06-12 20:46:16
【问题描述】:

vc2.h

@interface vc2 : UIViewController

@property (nonatomic, strong) NSDictionary *dict;

@end

vc2.m

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.dict = @{@"self":self};
    }
    return self;
}

根 VC

- (void)viewDidLoad {
    [super viewDidLoad];
    vc = [[vc2 alloc]init];
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:YES];
    vc = nil;
}

vc2 strong NSDictionary 属性持有 self 并且我在根 VC 中将 vc2 设置为 nil 但是当我在仪器中检查时 vc2 实例仍然存在。

当我设置weak NSDictionary 属性时,vc2 实例在设置为nil 后被释放,但是 Xcode 给了我这个警告 Assigning dictionary literal to a weak property;赋值后对象会被释放

这个内存管理是怎么回事?

【问题讨论】:

  • 尝试将弱自我放入数组中。

标签: ios objective-c swift memory-management memory-leaks


【解决方案1】:

好吧,如果对字典的引用是 strongvc2 会创建一个保留循环 - 它通过字典引用自己。因此,从根目录中删除对它的引用将无济于事,仍然会存在至少一个引用 - 来自字典的引用。

很简单——如果有一个对象的引用,它必须被保留,你不能释放它。由于vc2 持有对字典的引用,所以当vc2 存在时字典不能被释放。但是,字典本身包含对vc2 的引用,因此在字典存在之前不能释放vc2。这是保留循环 - vc2 使字典保持活动状态,而字典使 vc2 保持活动状态

您可以通过使用weak 引用类型来打破这个循环 - 弱意味着不会使用此引用来确定是否必须保留对象。从保留/释放的角度来看,weak 引用不算数。因此,当您创建字典属性weak 时,您是在说vc2 不应使字典保持活动状态。换句话说,您是说如果没有其他对象引用该字典,vc2 不应成为保留它的理由,在这种情况下可以释放字典。但是,因为当您在vc2 中创建字典时,对它的唯一引用是vc2 中的那个,weak 之一,没有strong 引用它会阻止释放它。结果如下:

// here you create a dictionary and assign it to your weak dict property
self.dict = @{@"self":self};
// but right here, after executing it, the only reference to the created dictionary
// is the weak one - that means that the dictionary can be released!
// thus, if you try to print dict right on the next line, it will be nil
// because it was released right after creation

这就是使用weak 引用字典的问题。每个对象只有在至少有一个 strong 引用时才会保留(存在)。但在这种情况下,可怜的字典不会得到一个 strong 引用。

您需要的是 strong 对字典的引用。这将确保字典在 vc2 存在时存在。但是您需要在某处打破保留周期。确定应该是什么weak 非常简单:只需询问哪个对象应该依赖于哪个:

  • vc2存在的情况下,可以发布字典吗?
  • 不,不能,字典应在vc2 存在时保留。
  • 可以在字典存在的情况下释放vc2 吗?
  • 可以!事实上,当vc2被释放时,字典也可以被释放。

这意味着字典依赖于vc2,反之亦然。因此,您需要从 vc2 到字典的强引用 - 这将确保在 vc2 存在时,字典存在。但是您不希望字典的存在使vc2 保持不变——当其他对象释放vc2 时,字典一定不能保持vc2 活着。因此,您需要从字典中引用weakvc2,而不是strong。这应该为您指明正确的方向 - 您添加到字典中的 self 引用应该是 weak

例如查看SO question 以获取有关如何处理字典中的弱条目的一些建议。

【讨论】:

  • 感谢您的回复,请您详细说明为什么将 vc 设置为 nil 不会清除 dict 中的 self,dict 对象在 vc 中,当整个类设置为 nil 时为什么它不能在 dict 上工作拿着self,dict中的self是另一个副本吗?
  • @Pursuingperfect 我试着详细解释一下。。dict 中的self 基本上是对vc2 的另一个引用,所以如果是strong,它将保留@987654365 @ 周围..
  • @Pursuingperfect 很高兴为您提供帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 2014-12-26
  • 2013-08-12
相关资源
最近更新 更多