gpt4 book ai didi

objective-c - 从 block 中关闭模态视图时 Dealloc 不运行

转载 作者:行者123 更新时间:2023-11-29 13:46:49 25 4
gpt4 key购买 nike

这里很奇怪,当从一个 block 中解雇时,并没有调用 dealloc。代码:

[[NSNotificationCenter defaultCenter] addObserverForName:@"user.login" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {

[self dismissModalViewControllerAnimated:YES];

}];

有人知道为什么会这样吗?我如何从 block 内部解雇并同时运行 dealloc?

我试过 self 执行选择器,但这没有任何区别。

谢谢

最佳答案

(1) 您的代码有误(不完整)。当您发出 addObserverForName: 时,您必须捕获返回值;这是观察者 token 。您将其存储在某处(例如实例变量):

self->observer = [[NSNotificationCenter defaultCenter] 
addObserverForName:@"woohoo" object:nil queue:nil
usingBlock:^(NSNotification *note)
{
//whatever
}];

稍后,当您不复存在时,您可以通过调用 removeObserver: 并将该观察者标记作为参数从通知中心删除该观察者标记。如果不这样做,稍后可能会崩溃。

[[NSNotificationCenter defaultCenter] removeObserver:self->observer];

(2) 但是等等,还有更多!在 ARC 下,复制 block 时,您将获得一个保留周期。这是因为存储的观察者 token 包含该 block 并且本身保留了 self 。我会给你三种方法来打破这个保留周期:

(a) 将观察者 token 存储为弱引用:

__weak id observer;

(b) 将观察者 token 存储为强引用,但在移除观察者时显式释放它(通过消除它):

[[NSNotificationCenter defaultCenter] removeObserver:self->observer];
self->observer = nil; // crucial

(c) 在创建 block 时像这样进行“弱-强舞蹈”(我假装 self 是 Fl​​ipsideViewController):

__weak FlipsideViewController* wself = self;
observer = [[NSNotificationCenter defaultCenter]
addObserverForName:@"user.login"
object:nil queue:nil usingBlock:^(NSNotification *note) {
FlipsideViewController* sself = wself;
[sself dismissModalViewControllerAnimated:YES];
}];

现在,正如我的一位评论者所暗示的那样,您可能认为“弱-强之舞”是一种极端的方法。但它有一个巨大的优势:它是这三种解决方案中唯一允许您在 dealloc 中删除观察者的解决方案。对于其他两个解决方案,dealloc 将永远不会被调用,直到您调用 removeObserver: 之后 - 找到一个更好的调用它的地方可能不会放轻松。

关于objective-c - 从 block 中关闭模态视图时 Dealloc 不运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7023894/

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