您的位置:首页 > 产品设计 > UI/UE

UIAlertController基本使用与内存泄露分析!!!

2017-10-09 14:44 169 查看
最近开发过程中,发现内存会无故增加,在做内存优化的过程中,无意间发现了内存泄露的情况,那就是从iOS8.0 苹果开始推荐我们使用的UIAlertController!!!

看到这你是不是会嘲笑我第一次使用UIAlertController,居然还会出现内存泄露?我想说你 too young, too simple, sometimes naive,不闹了,言归正传:这篇文章介绍

的知识点保证你从来没有注意到过,喜欢的点个👍,下方留言。。。

#pragma mark -- 基本使用

   //1.ActionSheet
UIAlertController * actionSheet = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[actionSheet addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
//进行后续删除的操作...
}]];
[self presentViewController:actionSheet animated:YES completion:nil];

//2.alert
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
//进行后续删除的操作...
}]];
[self presentViewController:alert animated:YES completion:nil];


#pragma mark -- 复杂操作(内存泄露)

因为UIAlertControllerStyleActionSheet 样式的弹框不支持添加textField不在继续探究内存泄露的问题了!

UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
//设置占位符,键盘样式什么的。。。
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[self doSomethingWithAccount:alert.textFields.firstObject.text withPassword:alert.textFields.lastObject.text];
}]];
[self presentViewController:alert animated:YES completion:nil];

- (void)doSomethingWithAccount:(NSString *)account withPassword:(NSString *)password
{
//进行删除操作。。。
}


在控制器中实现dealloc方法 发现返回到上一级界面后,该控制器也成功的被销毁了。说好的内存泄露呢?

内存泄露证明

1、使用工具(查看内存使用大小)

  因为我的XCode内存调试工具不能使用,只能使用其他的方法证明内存泄露了:最明显的就是内存增加,不断的弹框,然后点击确定,发现XCode的Memory不断的增加,测试发现内存占用从40M--->140M。

2、代码测试内存泄露 (查看是否销毁)

控制器销毁了,那么唯一可能内存泄露的就是alert弹框了! 没错!!! 相信你也一定想到,写一个类继承自UIAlertController 看看有没有走dealloc方法......

----------------------------------------------------------------------------------------------------------------------

EYAlertController.h

#import <UIKit/UIKit.h>

@interface EYAlertController : UIAlertController

@end


EYAlertController.m

#import "EYAlertController.h"

@interface EYAlertController ()

@end

@implementation EYAlertController

- (void)dealloc
{
NSLog(@"-----自定义弹框类EYAlertController销毁了----");
}

@end


在控制器中导入

#import "EYAlertController.h"

   EYAlertController * alert = [EYAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
//设置占位符,键盘样式什么的。。。
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {

}]];
[self presentViewController:alert animated:YES completion:nil];


弹框后点击取消或者确定,pop到上一个控制器。控制台输出:



弹框销毁了 测试控制器也销毁了 没有任何问题!!

-----------------------------------------------------------------------------------------------------------------

但是当我们添加下面这句话时:

[self doSomethingWithAccount:alert.textFields.firstObject.text withPassword:alert.textFields.lastObject.text];

控制没有输出任何语句,alert和控制器都没有销毁!!

就是这句话引起的内存泄露!!!

---------------------------------------------------------------------------------------------------

将弹框修改为如下代码

  __weak typeof(self) weakSelf = self;
EYAlertController * alert = [EYAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
//设置占位符,键盘样式什么的。。。
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf doSomethingWithAccount:alert.textFields.firstObject.text withPassword:alert.textFields.lastObject.text];
}]];
[self presentViewController:alert animated:YES completion:nil];


控制台输出:



证明: alert 自己没有及时回收导致了内存泄露!!!

原因分析: 因为测试环境是ARC环境,引起内存泄露的应该就是强引用循环了。而且是alert自己强引用循环了,alert没有销毁,又强引用着刚才的self才导致刚才的的控制器也没有销毁!!!

最终完美的的代码:

   EYAlertController * alert = [EYAlertController alertControllerWithTitle:@"提示" message:@"是否删除?" preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
//设置占位符,键盘样式什么的。。。
}];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
}];
[alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]];
__weak typeof(alert) weakAlert = alert;
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
__strong typeof(weakAlert) strongAlert = weakAlert;
[self doSomethingWithAccount:strongAlert.textFields.firstObject.text withPassword:strongAlert.textFields.lastObject.text];
}]];
[self presentViewController:alert animated:YES completion:nil];


控制台输出测试结果:



图例解释原因:





以上就是UIAlertController中添加textField 后的使用注意点。

总结:

1、测试发现内存不断升高,也有可能是控件自身的强引用循环。

2、以后使用自己不熟悉的控件,一定要继承该控件,使用自己的控件,重写dealloc方法,观察控件有没有及时的销毁。

更多内容--> 博客导航 每周一篇哟!!!

有任何关于iOS开发的问题!欢迎下方留言!!!或者邮件lieryangios@126.com 虽然我不一定能够解答出来,但是我会请教iOS开发高手!!!解答您的问题!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: