MMDrawerController 切换页面时不调用dealloc

本文探讨了iOS开发过程中遇到的内存泄漏问题,特别是由于NSTimer和代理强引用导致的内存问题。文章详细分析了如何避免这些常见陷阱,并给出了dealloc方法中资源释放的正确顺序。

开发中发现侧边栏切换时未走dealloc方法。内存飙升。

排查原因发现。controller里有nstimer.  因为

timer=[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(keepAliveTimer) userInfo:nil repeats:YES];

这个target:self 增加了VC的RetarnCount 如果不【timer invalidate】,就不会调用dealloc;


再然后,一个比较隐蔽的因素,你反过头去找找看,跟这个类有关的代理,嗯,对是代理,有没有强引用的属性啊?对,比如一个代理的delegate应该是 assign 的现在是retain,就是这个,它也会影响你不让你调用dealloc;



 PS:dealloc中的释放也是有顺序的,就好比创建时,先父类,再子类,释放的时候反过来,不然有几率会crash,至于原因。 ———————— 看了一个帖子,上面说:子类是父类的继承,比较NB,以至于要杀死他们的时候应该先干掉比较牛B的子类。 看完后我就记住了。很有意思~

在 UIKit 中实现页面返回刷新数据,通常涉及两个视图控制器之间的通信机制。可以通过 delegate 模式、闭包回调或通知中心(`NotificationCenter`)等方式实现。以下是几种常见的实现方法: ### 使用 Delegate 模式 在目标页面页面 B)定义一个协议,并在源页面页面 A)中实现该协议。当页面 B 被关闭调用代理方法通知页面 A 数据已更新。 ```objc // PageB.h @protocol PageBDelegate <NSObject> - (void)didUpdateData; @end @interface PageB : UIViewController @property (nonatomic, weak) id<PageBDelegate> delegate; @end // PageB.m @implementation PageB - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if ([self.delegate respondsToSelector:@selector(didUpdateData)]) { [self.delegate didUpdateData]; } } @end // PageA.m @implementation PageA - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.destination isKindOfClass:[PageB class]]) { PageB *pageB = (PageB *)segue.destination; pageB.delegate = self; } } - (void)didUpdateData { // 在这里执行刷新逻辑 } @end ``` ### 使用闭包回调 在页面 B 中定义一个 `block` 或 `closure` 属性,用于在页面关闭回调页面 A 的刷新逻辑。 ```objc // PageB.h typedef void(^DataUpdateBlock)(void); @interface PageB : UIViewController @property (nonatomic, copy) DataUpdateBlock updateBlock; @end // PageB.m - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if (_updateBlock) { _updateBlock(); } } // PageA.m PageB *pageB = [[PageB alloc] init]; pageB.updateBlock = ^{ // 执行刷新逻辑 }; [self.navigationController pushViewController:pageB animated:YES]; ``` ### 使用 NotificationCenter 通过 `NSNotificationCenter` 实现跨页面通信,页面 B 发送通知,页面 A 监听并响应数据更新事件。 ```objc // 页面 A 注册通知 - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshData) name:@"DataUpdatedNotification" object:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)refreshData { // 刷新数据逻辑 } // 页面 B 发送通知 [[NSNotificationCenter defaultCenter] postNotificationName:@"DataUpdatedNotification" object:nil]; ``` ### 通过 viewWillAppear 方法手动刷新数据 如果页面 A 需要每次显示都重新加载数据,可以在 `viewWillAppear:` 方法中执行数据刷新逻辑。 ```objc - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self reloadData]; // 手动刷新数据 } - (void)reloadData { // 加载最新数据的逻辑 } ``` 这种方法适用于数据来源是本地或网络请求且需要依赖页面 B 显式触发的场景。 ### 总结 同的方式适用于同的使用场景: - **Delegate 模式**:适合页面之间有明确的父子关系,且需要传递数据或状态变化。 - **闭包回调**:实现更简洁,适合轻量级的数据更新通知。 - **NotificationCenter**:适用于多个对象监听同一事件的情况,但需要注意避免内存泄漏。 - **viewWillAppear:**:适用于每次页面出现都需要刷新数据的通用情况。 选择合适的方式可以提高代码的可维护性和可扩展性。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值