http://www.cocoachina.com/ios/20151214/14596.html

在了解控制器的生命周期之后,我们都知道viewWillAppear:方法是在控制器的view将要显示的时候调用的,而viewWillDisappear:方法是在控制器的view将要隐藏的时候调用。很多时候我们根据自身需要将相关代码逻辑添加到这两个方法中,我们看下如下代码片段:

监听键盘的通知代码

这段代码是在控制器的viewDidLoad:方法中注册了一个键盘弹出的通知和键盘隐藏的通知,然后在调用到相关方法时分别在控制台打印,在viewWillDisappear:界面即将隐藏的时候移除通知,具体效果如下图:

代码运行效果图

这看上去没什么问题,键盘的显示和隐藏也都能监听到。尼玛!被骗了!?

其实并不然,细心的开发人员会知道,苹果在iOS7中增加了导航控制器侧滑返回功能,现在绝大多数App都使用了这项功能(有些App重写了自带的返回键之后忘记开启左滑返回手势了)。那么这项功能会带来什么问题呢?我们接着看下面的操作:

侧滑效果图

随着iPhone手机屏幕越来越大,左上角的返回按钮早已够不到(原谅我手小= =!),很多“手贱”的人喜欢通过这种侧滑的形式返回上一个界面(其实说的是我。。。),而这种侧滑返回会出现什么问题呢?当触发侧滑返回时会调用系统自带的viewWillDisappear:方法,在该方法中将监听键盘显示和隐藏的通知移除后,要是这时候用户取消了侧滑返回(即回到了原始状态),那么再点击界面上的textField唤出键盘,是不会发送键盘显示和隐藏的通知了,因为通知已被移除。。。

那么遇到这种情况有什么方法解决么?

我这里提供两种解决方案:

1、将注册监听键盘显示和隐藏的代码放到viewWillAppear:方法中

因为在触发侧滑返回后又取消侧滑,则会调用viewWillAppear:方法。那么如果侧滑返回将通知移除,则在取消侧滑时又会将通知重新添加进去。

2、将移除通知的代码放到dealloc方法中

dealloc方法是在控制器销毁之时调用的。这个时候移除通知而不是在viewWillDisappear:方法中移除可以有效避免上述的问题。既然控制器都销毁了,那么还留着相关的通知干嘛?该移除的移除。

上面给出了两种解决方案,要说哪种最优,那肯定非第二种莫属了。

我在这里可以举个例子。假如我们现在有这么个场景:在控制器的view上有个label,在label上添加一个手势(一般手势都是在创建完label之后添加的),假设我在viewWillDisappear:方法中移除该手势,则此时用户侧滑返回之时又取消侧滑返回,那么原先在label上的手势却再也添加不回来了(这里label一般在viewDidLoad方法中创建),因为viewDidLoad方法不会再次调用。而第二种方法却可以有效避免这种情况,这样就可以避免我这种“手贱”的任意捣鼓了,是不是很完美呢?

最后,我们再来总结下重点:

1、iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法。

2、在做手势和通知等一系列操作之时尽量在dealloc方法中执行,添加通知尽量在viewDidLoad等一次性方法中执行。

3、在viewWillAppear:、viewWillDisappear:、viewDidAppear:、viewDidDisappear:等类似于这种会多次调用的系统方法中添加代码时,一定要多考虑业务逻辑,以免出现不必要的麻烦。

 
 

iOS尽量不要在viewWillDisappear:方法中移除通知的更多相关文章

  1. 尽量不要在viewWillDisappear:方法中移除通知

    1.iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法.   2.在做手势和通知等一系 ...

  2. 不要在viewWillDisappear:方法中移除通知

    都知道viewWillAppear:方法是在控制器的view将要显示的时候调用的,而viewWillDisappear:方法是在控制器的view将要隐藏的时候调用. 这看上去没什么问题,键盘的显示和隐 ...

  3. iOS tableViewCell 在自定义高度方法中遇到的问题,cell高度为0,cell显示不出来,cell直接显示第几个而不是...cell显示个数不对

    遇到以上问题可以看看你的cell高度中是否有,自定的高度,有了继续看,没有了继续百度... 在文字排版中,少不了自适应文字高度,行间距什么的:显然cell的高度时不固定的,如果复用自定义的cell的话 ...

  4. iOS NSNotificationCenter 移除通知带来的crash

    Where to remove observer for NSNotification? 在dealloc方法中移除通知观察者带来crash NSNotificationCenter中的通知消息已经发 ...

  5. 为什么不要在viewDidLoad方法中设置开始监听键盘通知

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个普遍的错误是,程序猿(媛)试图在view controll ...

  6. iOS之创建通知、发送通知和移除通知的坑

    1.创建通知,最好在viewDidLoad的方法中创建 - (void)viewDidLoad { [super viewDidLoad]; //创建通知 [[NSNotificationCenter ...

  7. iOS 处理方法中的可变參数

    ## iOS 处理方法中的可变參数 近期写了一个自己定义的对话框的demo,想模仿系统的UIAlertView的实现方式.对处理可变參数的时候,遇到了小问题,于是谷歌了一下.写下了处理问题的方法.记录 ...

  8. [ios]IOS的AppDelegate方法中的事件触发调用 以及 关闭 ios应用程序

    IOS的AppDelegate方法中的事件触发调用 参考:http://blog.sina.com.cn/s/blog_a573f7990101bphp.html //当应用程序将要进入非活动状态执行 ...

  9. 【转载】C#中string类使用Remove方法来移除指定位置的字符

    在C#的字符串操作过程中,有时候需要将字符串中指定位置的字符移除,此时就可能使用到字符串类string类中的Remove方法,此方法允许指定移除开始的开始的索引位置,以及移除的长度信息等,共有2个重载 ...

随机推荐

  1. redis-cli启动问题

    首先需要找到redis的所在目录,然后将redis.conf复制到/etc/redis.conf 另外需要将redis.conf文件中的 daemonize no 设置为 daemonize yes. ...

  2. 匿名/局部内部类访问局部变量时,为什么局部变量必须加final

    我们都知道方法中的匿名/局部内部类是能够访问同一个方法中的局部变量的,但是为什么局部变量要加上一个final呢? 首先我们来研究一下变量生命周期的问题,局部变量的生命周期是当该方法被调用时在栈中被创建 ...

  3. 学习mysql数据库

    1.数据库是怎么回事 数据库是存储数据的永久空间,通过一种特殊的方式存储到硬盘中 数据库分为关系型数据库和非关系型数据库 mysql查看数据的方式为:结构化查询语言(SQL语句) 访问mysql数据库 ...

  4. opencv读取的彩色图像,数据是GBR而不是RGB

    开发久了,容易想当然 直到数据怎么也不对的时候,才想起来查一下手册 三个像素,当然没有这么大的像素,这是放大之后的 数据输出

  5. jmeter是什么

    Apache JMeter 是Apache 组织开发的基于 Java 的压力测试工具: 适用的测试领域:地方 用于对软件做压力测试,它可以用于测试静态和动态资源,例如:静态文件,Java 小程序.CG ...

  6. 2019-2-19-win10-uwp-客户端如何发送类到-asp-dotnet-core-作为参数

    title author date CreateTime categories win10 uwp 客户端如何发送类到 asp dotnet core 作为参数 lindexi 2019-2-19 9 ...

  7. 【vue移动端架子】vue-h5-template

    作者大大的地址:https://github.com/sunnie1992/vue-h5-template 我们运行项目,倒是可以看一看效果 虽然就是显示的UI,但是应该可以知道作者大大想要什么东西了 ...

  8. Redis源码解析:19Hiredis异步API代码解析

    Hiredis中的异步API函数需要与事件库(libevent,libev, ev)一起工作.因为事件循环的机制,异步环境中的命令是自动管道化的.因为命令是异步发送的,因此发送命令时,必要情况下,需要 ...

  9. falsh 遮住div 解决方案

    1.修改代码 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http ...

  10. JavaScript数据存储和深浅拷贝实际运用

    JavaScript分两种数据类型.1.简单数据类型有:number, string, boolean, undefined和null当声明一个简单数据类型的变量时,在内存中会把数据存在栈里.2.复杂 ...