上回书说AFN多线程崩溃实难重现, 这回的崩溃是不定概率重现的,
今天来说下animated隐式动画的血与泪.

前几天我在玩网易云音乐的手机端时,发现一个有趣的效果

图片 1粒子效果.gif图片 2粒子特效-百度百科.png

不定概率重现的BUG或者CRASH往往可以从以下几个角度分析.

图片 3网易云音乐页面部分截图

创建发射源

 emitterLayer = [CAEmitterLayer layer];

1 时序问题没处理好. 本来觉得可能先来的通知却后到了,
而你的例如初始化操作可能因此错过, 这就导致了异常.2 超时没处理.
发送网络请求都有可能没有回调,
无论是通知(Notification)、块还是代理方式, 都需要对网络超时有处理,
否则写出的代码是不鲁棒的.3 网络返回的数据有异常. 比如,
你发一个HTTP请求希望得到一个数组的结果, 可服务端却返回一个字典,
但你代码里面对数据的解析都是针对字典的, 这里如果不加保护就一定会崩溃.
(不要鄙视我说这点, 就是工作了近10年的老程序员也可能会忽略这个保护).4
用户手太快. 我们在开发的过程中, 通常是按照常理,
按部就班的点击按钮进行操作, 但APP在用户手中是如果点击的谁也说不准,
这样, 我们在开发中就应该重视方法的触发会造成什么后果,
一个方法多次调用(可能是不存在的, 可能是存在的,
但是你想不到)会不会影响程序的运行, 都是我们应该重视的(这点我深信,
初学开发的人是绝对不会去考虑的).

如上图,因为我最近在玩阴阳师的游戏,所以给网易云设置了皮肤,可以看出tabbarItem比平常的要高,而我所得有趣的效果就是当我点击我用红色曲线圈起来的区域时,是tabbar在响应点击事件,从而切换页面,而当我点击蓝色箭头所指的区域时,是tableView
的 cell在响应点击事件,从而开始播放这首歌曲。

设置粒子发送器 每秒钟发送的数量

emitterLayer.birthRate = self.emitterBirthRate?self.emitterBirthRate:1.0f;

今天我们要重现的就是应对用户手快这种崩溃,
顺便说下animated隐式动画的血泪史.

从事iOS开发的同学都知道,iOS的控件都是矩形的,像这样的特殊效果,给人的感觉就好像是这四个tabbarItem是不规则的形状一样

发射源位置

emitterLayer.emitterPosition = emitterPosition;

有一定开发经验的人通常都不会使用系统自带的UINavigationController,
因为这个Controller的BUG实在太多,
如果线上版本使用此Controller估计你会哭的很有节奏.
网上会有很多对UINavigationController的封装, 有带block的, 有排队的,
你会写一个类似isViewInTransition的flag, 来标志是否有vc正在做动画呢,
但都不见得能避免我们今天说的问题.

我所想到的解决方法是:监听手指点击的点的图片的像素是否透明,如果透明,则tabbar不响应事件,则根据响应链的特性,其下方的tableView就会响应点击事件

发射源尺寸

emitterLayer.emitterSize = emitterSize;
[self.navigationController popViewControllerAnimated:YES];[self.navigationController pushViewController:vc animated:YES];

想到方法后,我便开始了百度,😁😄

发射形状的样式

emitterLayer.emitterShape = kCAEmitterLayerLine;

你可能会在项目中写过类似这种代码吧, 先pop一个, 然后立马push,
在加了排队处理逻辑后, 这样写是没问题的, 当animated == YES的时候,
把后续的操作放入一个队列,
didShowViewController后再去执行队列里面的操作. 当然有了队列,
你写下面的代码也是没问题的.

首先找到了这样一篇博客:iOS实现UIImageView透明区域点击事件穿透(这篇博客也是转载的:原文链接在博客下方:原文链接)

发射模式

emitterLayer.emitterMode = kCAEmitterLayerPoints;

发表评论

电子邮件地址不会被公开。 必填项已用*标注