UIActionSheet关闭动画过程中调用delegate = nil 导致的内存泄露
来源:互联网 发布:bbs论坛数据库设计 编辑:程序博客网 时间:2024/06/15 08:06
UIActionSheet在动画期间(ActionSheet button点击之后,到didDismissWithButtonIndex调用完成之前)设置delegate为空会导致delegate无法释放。
先来看个例子:
例子中创建一个UIActionSheet,并在按钮点击之后0.1秒(关闭动画结束前)设置delegate = nil。
#import "LIViewController.h"@class UIActionSheetDelegateImpl;static UIActionSheetDelegateImpl * delegateImpl; @interface UIActionSheetDelegateImpl : NSObject <UIActionSheetDelegate>@end@implementation UIActionSheetDelegateImpl// Called when a button is clicked. The view will be automatically dismissed after this call returns- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{ NSLog(@"%s", __func__); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ delegateImpl = nil; }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ actionSheet.delegate = nil; });}- (void)actionSheetCancel:(UIActionSheet *)actionSheet{ NSLog(@"%s", __func__);}- (void)willPresentActionSheet:(UIActionSheet *)actionSheet{ NSLog(@"%s\n", __func__);}- (void)didPresentActionSheet:(UIActionSheet *)actionSheet{ NSLog(@"%s\n", __func__);}- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex{ NSLog(@"%s\n", __func__);}- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex{ NSLog(@"%s\n", __func__);}- (void)dealloc{ NSLog(@"%s\n", __func__);}@end@interface LIViewController ()@end@implementation LIViewController- (void)viewDidLoad{ [super viewDidLoad];}- (void)viewDidAppear:(BOOL)animated{ delegateImpl = [UIActionSheetDelegateImpl new]; UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"测试" delegate:delegateImpl cancelButtonTitle:@"cancel" destructiveButtonTitle:@"ok" otherButtonTitles:nil, nil]; [actionSheet showInView:self.view];}@end
输出为:
[UIActionSheetTest[62028:60b] -[UIActionSheetDelegateImpl willPresentActionSheet:][UIActionSheetTest[62028:60b] -[UIActionSheetDelegateImpl didPresentActionSheet:][UIActionSheetTest[62028:60b] -[UIActionSheetDelegateImpl actionSheet:clickedButtonAtIndex:][UIActionSheetTest[62028:60b] -[UIActionSheetDelegateImpl actionSheet:willDismissWithButtonIndex:]
可以看到 UIActionSheetDelegateImpl delloc和actionSheet:willDismissWithButtonIndex并未调用, 也就是说UIActionSheetDelegateImpl对象并未释放。
当去掉delegate = nil调用时输出结果如下:
[UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl willPresentActionSheet:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl didPresentActionSheet:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl actionSheet:clickedButtonAtIndex:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl actionSheet:willDismissWithButtonIndex:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl actionSheet:didDismissWithButtonIndex:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl dealloc]
或者延长delegate = nil 调用时间为0.5秒之后(UIActionSheet关闭动画结束)也会输出上面结果, 也就是delegate = nil在actionSheet:didDismissWithButtonIndex:之后调用也能释放delegate。
如果直接在actionSheet:clickedButtonAtIndex:调用delegate = nil(actionSheet:willDismissWithButtonIndex:和actionSheet:didDismissWithButtonIndex:不会调用),dealloc能正常调用, 输出结果如下:
[UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl willPresentActionSheet:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl didPresentActionSheet:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl actionSheet:clickedButtonAtIndex:][UIActionSheetTest[62086:60b] -[UIActionSheetDelegateImpl dealloc]
# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller0 Malloc +1 1 00:06.236.929 UIActionSheetTest -[LIViewController viewDidAppear:]1 Retain +1 2 00:10.498.951 UIKit +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:]2 Release -1 1 00:11.286.073 libdispatch.dylib _dispatch_client_callout
如果在动画之后调用delegate = nil
# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller0 Malloc +1 1 00:01.150.499 UIActionSheetTest -[LIViewController viewDidAppear:]1 Retain +1 2 00:02.919.288 UIKit +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:]2 Release -1 1 00:03.328.439 UIKit -[UIViewAnimationState sendDelegateAnimationDidStop:finished:]3 Release -1 0 00:04.286.073 libdispatch.dylib _dispatch_client_callout
动画之前调用delegate= nil,结果如下:
# Event Type ∆ RefCt RefCt Timestamp Responsible Library Responsible Caller0 Malloc +1 1 00:06.236.929 UIActionSheetTest -[LIViewController viewDidAppear:]1 Release -1 0 00:04.286.073 libdispatch.dylib _dispatch_client_callout
从中可以看到, 当_setupAnimationWithDuration和sendDelegateAnimationDidStop不配对时delegate就不能释放。
0 1
- UIActionSheet关闭动画过程中调用delegate = nil 导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- performSelector延时调用导致的内存泄露
- PerformSelector延时调用导致的内存泄露
- QT中使用槽函数来关闭窗口,导致内存泄露的问题以及解决办法
- Volley中listener导致的内存泄露
- HashMap存取过程中改变key值导致的内存泄露
- opendir 未关闭导致内存泄露
- Delegate未设为nil导致的thread 1:exc_bad_access(code=EXC_I386_GPFLT)
- 错误调用CreateToolhelp32Snapshot导致内核内存泄露
- fork 导致的内存泄露
- RS485、RS422、RS232中的RS指什么呢?
- LeetCode First Missing Positive
- 初识JAVA,对servlet的理解
- 线性规划与网络流24题之最小路径覆盖问题
- lua的堆栈(摘要)
- UIActionSheet关闭动画过程中调用delegate = nil 导致的内存泄露
- 适配器模式
- Building Plugins for iOS
- 用java的一个复制图片程序
- 简单获取数据库连接串
- leetcode:Triangle
- NanShan 如何解决DotProject中文乱码问题
- 五个字乘以4等于倒过来的值,四个字乘以4等于倒过来的值
- JavaBean的简单用法