为什么UIAlertController用self创建一个保留周期? [英] Why does UIAlertController create a retain cycle with self?

查看:94
本文介绍了为什么UIAlertController用self创建一个保留周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"action" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    [self doSomething];
}];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];

我了解周期. self保留UIAlertControllerUIAlertController保留UIAlertActionUIAlertAction保留self

I understand the cycle. self retains the UIAlertController, UIAlertController retains the UIAlertAction, UIAlertAction retains self

我的意思是,在内部运行一个UIAlertActions之后,此类不能设计为释放所有内容吗?

-

为了澄清这一点,我知道可以通过使用对自身的弱引用来避免此问题.

To clarify, I know that this issue can be avoided by using a weak reference to self.

我要问的是为什么一旦用户选择了一个动作,为什么UIAlertController就不取消所有动作(以及它们的处理程序块)呢?这样可以打破循环,避免我们需要做的整个弱者舞蹈.

What I am asking is why doesn't UIAlertController just nil out all the actions (and hence their handler blocks) once an action has been selected by the user. This would break the cycle and avoid the whole weakself dance we need to do.

类似这样的事情...

Something like this...

@implementation UIAlertController

...

// An action button was pressed
- (void)actionSelectedIndex:(NSInteger)index
{
    UIAlertAction *action = self.actions[index];
    action.handler(action); // Run the action handler block
    self.actions = nil; // Release all the actions
}

推荐答案

这里的问题和答案使我感到困惑,这是我搜索结果的重头戏,所以我想保持记录直截了当:

The question and answers here baffled me, and this is on top of my search results so I'd like to set the record straight:

该示例中没有保留周期,因此在这种情况下无需创建弱自我".唯一有保留周期的时间是自我是否对警报有强烈的参考.

There is no retain cycle in the example, so there is no need to create a "weak self" in this case. The only time that there's a retain cycle is if self has a strong reference on alert.

UIAlertController旨在在执行完所有内容后释放所有内容,只要您没有对其的强烈引用即可.

UIAlertController has been designed to release everything after it has been executed, provided you don't hold a strong reference to it.

我在一个示例类中尝试了该示例,并且在控制器弹出时成功调用了dealloc.

I tried the example in a sample class, and dealloc was successfully called on pop of the controller.

通过示例进行总结:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"alert" message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"action" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    //No retain cycle, no need for weak self
    [self doSomething];
}];
[alert addAction:action];
[self presentViewController:alert animated:YES completion:nil];

vs

//assume this is a strong reference
self.alert = [UIAlertController alertControllerWithTitle:@"alert" message:nil preferredStyle:UIAlertControllerStyleAlert];
__weak __typeof(self)weakSelf = self;
UIAlertAction *action = [UIAlertAction actionWithTitle:@"action" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
    //Need a weakSelf to avoid retain cycle
    [weakSelf doSomething];
}];
[self.alert addAction:action];
[self presentViewController:self.alert animated:YES completion:nil];

侧面说明:假设您将自身放在块中时始终需要对自身使用弱引用是错误的.

Side note: It's wrong to assume that you always need to use weak reference to self when putting it in blocks.

这篇关于为什么UIAlertController用self创建一个保留周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆