这边最首要以iOS和OSX讲讲crash闪退怎么防御,在你的门类中参加这一行代码就可集成

LYEmptyView

此框架是自我在5,5个月前,集团启动新品类的时候,一起起来入手编制的,经过这几个类其他阐明与考验,不断的进行完善,在此特将那份框架分享出去供大家参考与上学。
github地址:https://github.com/yangli-dev/LYEmptyView

不需求坚守协议,不须求安装代理,不须求实现代理方法,只需这一句代码,就可为一个UITableViwe/UICollectionView集成空白页面占位图。self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

timg.jpeg

图片 1

目录

  • 一 效果呈现
  • 二 使用参考示例
    • 1 一行代码集成空内容视图
    • 2 自由选取空内容元素
    • 3 自定义空内容元素
    • 4 自定义元素的UI样式
    • 5 二次封装
    • 6 推迟显示emptyView
    • 7 格外须要,手动控制emptyView的体现隐藏

前言

那里根本以iOS和OSX讲讲crash闪退怎么防御。
其中最新的OSX应用本身就有早晚闪退防御,但有些类似@try @catch在最外层包了须臾间见惯不惊的越界调用空方法都会暂停在操作地点不向下执行,倘诺没有进一步复杂逻辑不会闪退,只是影响三番五次的操作。

而iOS则没这么好说话了,二话不说直接闪退给你看没有上边的那种机制。

故此才有了安排一个安保系统的含义,来保管最大程度的健壮性,理想的情事就是不crash且能继续健康运行后边的逻辑。

参考了许多网上的素材有了下边的小成果分享出来,那实在只是安保连串末段的一个环节的看守

https://github.com/heroims/SafeObjectProxy

1.

一 效果显示

show.gif

ImitateOtherApp.png

安保种类规划

此地自己所认为的安保系统应该从代码和业内几个层面看,毕竟想抓到所有的crash景况是必然不容许的,现实中就是四处try
catch都无法有限帮助抓到所有crash!

你是还是不是每一天去教室?

二 使用参考示例

代码

  • swizzing切面
  • 办法防御选型
  • 防卫成功申报

先后内亟待的是代码,那些模块是要没有其他侵入性的,所以切面是必须的,其次就是尽可能的细化切面颗粒度有限支撑意外景况最小化!

另一些就是切面未来大家对原方法应该利用哪些的防守,那里即可以try catch的样式也足以举办逻辑判断方式。
而自己的代码里用逻辑判断,越来越多的勘查是针对的函数都偏下层且便于选用时外部恰巧又有各个循环逻辑,那样相较之下try catch在不间断的调用性能会有自然影响,所以暂时失效try catch用作防守的一手。
从另一角度看其实try catch的采纳情况有些措施仍然相比较合适的,首先我们在戍守时办法颗粒度已经很细所以抓住很是都会做对应处理不会有内存泄漏或逻辑遗漏,此外无论try依然catch内的艺术也不会太多,满意了`try
catch的超级场景,只是独家方法循环使用略过高或者性能没办法到达极致仅此而已。

防守完了crash就是上报,大家维护了先后的同时也就表示有地点写的有题目,由于没crash所以没crash
log,那时候就必要在安保模块里进入报告机制,这时候我的做法则是放出一个商谈等人去落实,安保模块就专心处理防御的作业,上报到服务端的业务交给专门处理那事的模块,大家只必要在防卫成功时报告协议有诸如此类个工作即可。剩下的就是个体看情状如需详细情况直接[NSThread callStackSymbols]把栈信息输出一下!

//安保模块上报协议
@protocol SafeObjectReportProtocol

@required
/**
 上报防御的crash log

 @param log log无法抓到Notification的遗漏注销情况
 */
-(void)reportDefendCrashLog:(NSString*)log;

@end

而落到实处那个协议的只必要对SafeObjectProxy做个Category完成一下即可。

还有就是防御的分类开启,那时候枚举就要用位运算的样式,这样才能匹配多种方式共存如下只开启Array和String的守护

[SafeObjectProxy startSafeObjectProxyWithType: SafeObjectProxyType_Array| SafeObjectProxyType_String]

是。

1 一行代码集成空内容视图

//框架方法
self.tableView.ly_emptyView = [LYEmptyView emptyViewWithImageStr:@"noData"
                                                        titleStr:@"暂无数据,点击重新加载"
                                                       detailStr:@""];

PS:可对框架举办二次封装,调用更简单(二次封装方法在底下的演示5中会讲到)

//二次封装方法,调用简洁
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

全盘低耦合,在您的品种中投入这一行代码就可集成
无论项目中是reloadData方法刷UI仍然insert、delete等措施刷UI,不需做任何任何操作,只需这一行代码就可完毕以下功效

example1.gif

规范

另一个安保模块的三结合则应该是对代码规范的创立与校验,那就要求clang来做了,不是此处首要讲的,约等于多了一种Build OptionsCompiler for C/C++/Objective-C性能的取舍,用大家付出的Xcode校验插件,检查代码语法上的题材一贯报错,那样从源头来规范化编码。

您是否天天跟自家同一的爬楼梯到四楼?

2 自由采用空内容元素

交互事件可选择SEL或block方式
SEL交互事件:
self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                              titleStr:@"无数据"
                                                             detailStr:@"请稍后再试!"
                                                           btnTitleStr:@"重新加载"
                                                                target:target
                                                                action:action];
block交互事件:
self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                              titleStr:@""
                                                             detailStr:@""
                                                           btnTitleStr:@""
                                                         btnClickBlock:^{}];
//    imageStr    : 占位图片
//    titleStr    : 标题
//    detailStr   : 详细描述
//    btnTitleStr : 按钮标题                                                         

框架提供八个要素,传入相应元素的字符串即可突显对应元素(按钮的显示前提是传播target,action或btnClickBlock)
可根据项目须求,自由举办组合,如下只体现了有些组效率应

example2.png

Crash分类及防御已毕

  • Unrecognized Selector(找不到艺术)
  • UI Refresh Not In Main Thread(UI刷新不在主线程)
  • Input Parm Abnormal(入参非常)
  • Dangling Pointer(野指针)
  • Abnormal Matching(非常配对)
  • Thread Conflict(线程争执)

想要防御crash,首先要做的就是询问都有啥情形会生出crash,上面就是小编统计的三种最常见的情事,不全的话希望有人留言补足,毕竟crash的防卫真正有发言权开发那种模块的估量唯有大商厦开发app的,不然用户量不够没样本采集,无法领会坑爹的景况!

而地点列的6种常见crash,真正能广域控制得了的或是也只有一半不到!上边就相继讲解一下,Hook切面就是重视的手腕!

是。

3 自定义空内容元素

破例情况下,倘若空内容状态布局不满足需求时,可进行自定义
透过措施+ (instancetype)emptyViewWithCustomView:(UIView *)customView;
盛传一个View 即可创制一个自定义的emptyView

self.tableView.ly_emptyView = [LYEmptyView emptyViewWithCustomView:customView];

example3.png

Unrecognized Selector(找不到艺术)

那个找不到点子算是比较好办的。。。也算是相比普遍的好查的,此外处理ok了null对象调用的问题也会跟着缓解
可选的点子有两种
Hook那多个法子
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
- (void)forwardInvocation:(NSInvocation *)anInvocation
或Hook那些方式
-(id)forwardingTargetForSelector:(SEL)aSelector

核感情想就是在找不到方法之前创建方法确保继续执行不挂,为了尽可能不多余的创立方法,集中的把创造打到统一的地点。

前端须要在methodSignatureForSelector施行前在新的target里成立没有的法门,然后用它调用methodSignatureForSelector重临,而那边的target当然要单例弄出来省的未来来回创制。然后在forwardInvocation里用她来调用invokeWithTarget指到大家新的target上。

后来人也就是自我用的主意,之所以用它最重如若一个主意
就ok!而我辈还要兼顾静态方法和实例方法去分别hook才能防住那三种,而前者也要hook的措施愈来愈多。。。。
而那里只须要切forwardingTargetForSelector艺术,静态方法再次来到class,动态方法重返target,当然重返以前大家要添加上不设有的主意,值得注意的是OSX上一个神奇的题材,我在认清是或不是系统有其一法子的时候第四遍甚至respondsToSelector返回false而methodSignatureForSelector有数据,第二次校验是methodSignatureForSelector才为空,而iOS上则没那题目首先次校验就是对的!

你是否刚刚在贴纸条?

4 自定义元素的UI样式

那里自定义UI样式须要过多代码,别担心,在演示5中会讲解二次封装的方法,封装后调用时就只须求一行代码了
^ _ ^

  //初始化一个emptyView
  LYEmptyView *emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                           titleStr:@"无数据"
                                                          detailStr:@"请稍后再试!"
                                                        btnTitleStr:@"重新加载"
                                                      btnClickBlock:^{}];
  //元素竖直方向的间距
  emptyView.subViewMargin = 20.f;
  //标题颜色
  emptyView.titleLabTextColor = MainColor(90, 180, 160);
  //描述颜色
  emptyView.detailLabTextColor = MainColor(180, 120, 90);
  //按钮背景色
  emptyView.actionBtnBackGroundColor = MainColor(90, 180, 160);

  //设置空内容占位图
  self.tableView.ly_emptyView = emptyView;

那里只列举了部分常用的性质,更加多属性请到LYEmptyView.h查看

example4.png

UI Refresh Not In Main Thread(UI刷新不在主线程)

刷新UI不在主线程的动静那里只是对准UIView和NSView的3个措施做切面线程判断。分别是setNeedsLayout,setNeedsDisplay,setNeedsDisplayInRect,执行此前看是否在主线程,不在的话就切到主线程执行,但很分明那3个主意自然覆盖不全,而且就是覆盖全了历次都认清一下也是性质浪费,所以这边分别讨论处理吧,那类意况临时没悟出其余好的处理格局!但好在算是有诸如此类个可控方案!

是。

5 二次封装

第4小节的示范代码,修改emptyView的体裁要求一个个特性单独去改,假若项目中各样界面都这么写就显得很麻烦,而且不易维护
解决办法是对库开展二次封装,二次封装后,对UI样式单独管理,方便维护

Input Parm Abnormal(入参卓殊)

入参卓殊那是一大类,防御的主意也针锋相对比较通俗易懂,也是最简单查最简单现身的。

那你还敢说您不希罕我?

1)新建一个类继承自LYEmptyView,例如demo中的MyDIYEmpty

常用类型入参十分

常见类包涵String,Array,Dictionary,URL,FileManager等那几个类空值起先化,越界取值,空赋值等,基本看crash
log总计依次切面对应措施在履行前判断一下就ok。如objectAtIndex,objectAtIndexedSubscript,removeObjectAtIndex,fileURLWithPath,initWithAttributedString,substringFromIndex,substringToIndex等等。唯一要求留意的就是那一个要切面的类名不过五花八门并且更iOS版本有很大关系,所以那些就是靠crash
log积累明白有何样坑。当然代码写的好就用不到了!__NSSingleObjectArrayI本条就是近年在iOS11上新意识的报错数组类,当然也说不定是近期我司有人写出了这几个相关的bug……
大面积的内需专注的hook的类有以下
objc_getClass("__NSPlaceholderArray")
objc_getClass("__NSSingleObjectArrayI")
objc_getClass("__NSArrayI")
objc_getClass("__NSArrayM")
objc_getClass("__NSPlaceholderDictionary")
objc_getClass("__NSDictionaryI")
objc_getClass("__NSDictionaryM")
objc_getClass("NSConcreteAttributedString")
objc_getClass("NSConcreteMutableAttributedString")
objc_getClass("__NSCFConstantString")
objc_getClass("NSTaggedPointerString")
objc_getClass("__NSCFString")
objc_getClass("NSPlaceholderMutableString")
实际有怎么样方法必要切面如故看源码吧,这一部分是没什么难点的。

此外我的防御里面没对NSCache做,可能将来会随便加点,因为缓存相关的模块我的指出是温馨包装缓存模块或用第三方,那样对于上层使用者来说早已是高枕无忧的了!各样非凡处理在缓存模块里就应该有包装。

陆衔一跳进黄河也洗不清了,他不久前实在天天来体育场馆,这是因为最近的调研报告有太多关于天文方面的素材要求她找,他每一日爬楼梯是因为打小就无法在窄小的关闭空间呆着,至于那杯水,他不过就是不小心碰掉了杯子上的便利贴打算沾回去而已。

2)重写- (void)prepare 方法,并修改想要改变的因素的UI样式
- (void)prepare{
    [super prepare];

    self.titleLabFont = [UIFont systemFontOfSize:25];
    self.titleLabTextColor = MainColor(90, 180, 160);

    self.detailLabFont = [UIFont systemFontOfSize:17];
    self.detailLabTextColor = MainColor(180, 120, 90);
    self.detailLabMaxLines = 5;

    self.actionBtnBackGroundColor = MainColor(90, 180, 160);
    self.actionBtnTitleColor = [UIColor whiteColor];
}

操作上边的两步就可达成对体制的单身保管
调用方法不变,只是调用的类成为了MYDiyEmpty

self.tableView.ly_emptyView = [MYDiyEmpty emptyActionViewWithImageStr:@"noData"
                                                             titleStr:@"暂无数据"
                                                            detailStr:@"请稍后再试!"
                                                          btnTitleStr:@"重新加载"
                                                        btnClickBlock:^{}];

KVC Crash

KVC追根究底也算那类入参非常,一共切面3个地方就够防御了!
-(void)setValue:(id)value forKey:(NSString *)key,
-(void)setValue:(id)value forKeyPath:(NSString *)keyPath
空值防御上边2个法子
-(void)setValue:(id)value forUndefinedKey:(NSString *)key
地点这几个尽管没有的属性做赋值操作时走的回调,倘若用到我的SafeObjectProxy要自定义种种类分裂的处理是足以不开启UndefinedKey防御的!

这一粘不要紧,庄喜喜认定她是写纸条的人,认定她是写纸条的人也没关系,要紧的是,陆衔一刚刚才看见纸条上写的是:假如您不和自己在联名,我不知晓我会做出怎么样业务来。

3)进一步封装展现的要素内容,比如无数据状态图、无网络状态图

在MYDiyEmpty.h定义方法+ (instancetype)diyNoDataEmpty;
在MYDiyEmpty.m已毕格局

+ (instancetype)diyNoDataEmpty{
    return [MyDIYEmpty emptyViewWithImageStr:@"noData"
                                    titleStr:@"暂无数据"
                                   detailStr:@"请稍后再试!"];
}

经过3步包装,自定义了UI样式,使管理更有利,使调用更简洁
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];


Dangling Pointer(野指针)

其一种Crash堪称经典!就是至极最难排查的,而那里大家能做的防御工作也不行点滴!
切实定位看看腾讯这几篇很有帮带!
怎么样稳定Obj-C野指针随机Crash(一)
什么样定位Obj-C野指针随机Crash(二)
怎么定位Obj-C野指针随机Crash(三)
大家只能去对已知的产出野指针的类进行防卫,找到crash的野指针开启Zombie
Objects,加上Zombies工具,然后想艺术不断增强复现率仍能的稳定到的。
咱俩的看守则是hook系统dealloc,判断要求做拍卖的类不走系统delloc而是走objc_desctructInstance放飞实例之中所兼有属性的引用和涉及对象,保障对象最小化。紧接着就须求来波isa swizzling了,因为普通野指针伴随着的还有就是调用没有的办法,或者是因为调用的那个机会是不正常的,各个数码的安全性都没了有限支撑,所以dealloc后去掉所有具有,再把原先的isa指向一个其余的类,而那几个类能把持有的调用方法指向一个空方法这么就起到了防守的法力。

能干那事的也只有NSProxy了,利用协议落实methodSignatureForSelectorforwardInvocation艺术,统一打到从前处理找不到点子自动创造的类中,也就是在NSProxy内完成地点Unrecognized Selector的防卫,这样有着对于野指针的调用就都是空了!
正因为上面的案由一旦开启了这么些防御,真正自由的时机就仍然有些,若是在野指针出现前触发了真正自由的逻辑,crash就如故会有些!
我在SafeObjectProxy里只是用野指针个数控制做确实自由,回头可能会卷入个block方便复杂意况的论断。

那年头年轻人的启事都早就改为威迫利诱了啊?

上面的两种示例,属于特殊必要,须求四行代码搞定,调用和MJRefrsh类似,必要先安装样式,然后展现和隐形

Abnormal Matching(卓殊配对)

这一类算是不提出做防守的!成对的不二法门处理极度像KVO,NS提姆(Tim)er,NSNotification都算,要求登记和废除。
那种气象本身的提出是联合封装独立模块调用统一的法门,令人不要求关怀注册和废除,主要写逻辑处理。从效果落成上做严苛限制,那样令人设想的就是怎么样把一个场馆融入到封装的不二法门中,而不是任意的写!
下边说下原因,由于挂号和撤销是分手写的
,所以选用意况,解决问题的章程都会持有极度灵活的操作,那实质上很吓人,先用KVO做一个举例顺便说一下那类防御如若真要做一般的做法是如何做。

陆衔一还没影响过来,就被庄喜喜挽上胳膊大模大样走出体育场馆了。

6 推迟呈现emptyView

如示例1图,框架自动按照DataSource计算是或不是突显emptyView,在空页面发起网络请求时,DataSource肯定为空,会自行展现emptyView,有的产品须要可能不指望那样,希望提倡呼吁时暂时隐藏emptyView。
本框架提供了多少个艺术可已毕此须要,多少个格局都是scrollView的归类,调用卓殊便利

 /**
   一般用于开始请求网络时调用,ly_startLoading调用时会暂时隐藏emptyView
   当调用ly_endLoading方法时,ly_endLoading方法内部会根据当前的tableView/collectionView的
   DataSource来自动判断是否显示emptyView
 */
- (void)ly_startLoading;

 /**
   在想要刷新emptyView状态时调用
   注意:ly_endLoading 的调用时机,有刷新UI的地方一定要等到刷新UI的方法之后调用,
   因为只有刷新了UI,view的DataSource才会更新,故调用此方法才能正确判断是否有内容。
 */
- (void)ly_endLoading;

*注意点:使用那多少个办法,请先将emptyView的autoShowEmptyView属性置为NO,关闭自动显隐

以下是调用示例(具体细节可参考demo中的demo2)

//1.先设置样式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.关闭自动显隐(此步可封装进自定义类中,相关调用就可省去这步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.网络请求时调用
[self.tableView ly_startLoading];
//4.刷新UI时调用(保证在刷新UI后调用)
[self.tableView ly_endLoading];

example6.gif

KVO

KVO那种crash即便要守护其实只好防御下边3种情状:
1.观察者或被观察者已经不存在了
2.撤销和增加的次数不般配
3.没写监听回调observeValueForKeyPath:ofObject:change:context:

而那3种情形我们来认真想想下开发的等级是或不是相似都会第一时间就被察觉!而且一旦是没经验的程序员写KVO大家是或不是都不敢用,会反复审查,而有经验的又不会犯上面的错。。。。
如若对地点的情形防御也很复杂,而且自己尝试并且用过许多第三方,都在我司稍微有点复杂的连串上挂了,不仅没能防御crash还造了crash,那种成对逻辑的灵活性万分高,你无法领会系统内部人家怎么用着玩的!
说一下防守下面的情状首先切面add、removeObserve是自然的,还要在具有的类里再加一个对象,那几个目的主要负责管理KVO下边就叫KVOController吧,让具有的观望者都成为了被观看者的一个性质,用map记录原来的观看者和keyPath等音信,那样添加或移除观看者就能判定是还是不是成对出现的,其它KVOController在dealloc时也得以因而map依次移除监听,而出于具有的监听回调其实都是由KVOController的observeValueForKeyPath:ofObject:change:context:通过[originObserver observeValueForKeyPath:keyPath ofObject:object change:change context:context]传递出去的当然没写监听回调的情事也得以判定了,但也是能一举成功那3个情景!

确实KVO暴发的恐惧的crash是移除时机不和寓目者或被观看者销毁有提到,而是跟大家的逻辑有关,一旦没在合适机会移除导致的crash排查起来超级讨厌!还有你在监听回调里处理逻辑有没有线程安全题材,这么些才是我们在上线前不难漏,排查又不佳排查的!

安保连串则是要维护上线后能正常运转,但是如同本人那边说的KVO,如若不在编码时期就做严刻规范,上线后出的问题也是平昔得不到防御的!

然后再来说说怎么界定大家的自由发挥,KVOController刚才说到的那里要求的是把它变形,把回调用block放出来,别的就是让它有单例格局和普通的实例情势,只有创设对象、关联监听和逻辑处理,一个KVOController能够是全局或属于一个对象,相当于可视化了KVO的见效周期,一目明白,那里让特殊逻辑适应大家的正规才是不利的安保思路。包涵NS提姆(Tim)er在内也也是这么可以搞个提姆(Tim)erController不过封装最好也别用NS提姆er精度不高,反正要卷入不如直接gcd,与其要手动保持成对不如大家就把逻辑封装好,让使用者忘掉成对的定义!但在开放的明天统统可以GitHub搜一波找些封装好的融洽再简单包装下,然后让集体依据规范开发即可。。。

KVO:KVOController正如推荐的一个KVO管理

“你欣赏我爱好的那么麻烦,心绪出现了问题,心病还需心药医,解铃还须系铃人,我有第一权利,我答应你就是了。”庄喜喜一路上嘴巴都没停过,大有救其于水火的凛然大义。

7 更加需要,手动控制emptyView的来得隐藏

在少数特殊界面下,有的tableView/collectionView有稳定的一部分死多少,其余的数目按照网络加载,那时根据以上的演示方法恐怕达不到那须求。
本框架提供其余的八个措施来解决这一个题材。

/**
 手动调用显示emptyView
 */
- (void)ly_showEmptyView;

/**
 手动调用隐藏emptyView
 */
- (void)ly_hideEmptyView;

*注意点:使用那三个方法,请先将emptyView的autoShowEmptyView属性置为NO,关闭自动显隐

以下是调用示例(具体细节可参看demo中的demo4)

//1.先设置样式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.关闭自动显隐(此步可封装进自定义类中,相关调用就可省去这步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.显示emptyView
[self.tableView ly_showEmptyView];
//4.隐藏emptyView
[self.tableView ly_hideEmptyView];

example7.gif

欢迎star
github地址:https://github.com/yangli-dev/LYEmptyView

NSTimer

NS提姆er相比较奇特,有些时候偏偏不应当成对使用,它的成对的逻辑其实是跟自己的生命周期有关,毕竟生命周期截止时要去成对的停掉timer才能放出,另一些就是NS提姆er精确度并不高!但它包裹出来给人用的法门是ok的正是有单例格局和实例格局两种选用。所以自己的指出当然是友好把gcd的timer封装一下,此外把target那几个定义变为weak持有,那样我们团结一心包装的timer就足以dealloc的时候停掉timer释放了,根据系统NS提姆(Tim)er封装方法即可。那样至少能保险timer指定的target释放时timer能停掉不会因为跑了其余不安全的逻辑挂掉。别的可能挂掉的动静应该比较少。。。

Timer:MSWeakTimer正如推荐的一个计时器封装方法就是自个儿上边讲的那种

“你在干嘛?”陆衔一不晓得现在到底是什么情状。

NSNotification

本条尽管也是成对使用,单比地方的多少个要安全一些,因为使用它有[[NSNotificationCenter defaultCenter] removeObserver:self]频繁调用或没addObserver都不会挂,所以能够全局搞一下,我在SafeObjectProxy中间就只是对具有NSObject目标添加了个特性做标识,然后hook一下NSNotificationCenter-(void)addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject方法,只要observer是NSObject对象自我就标识一下,然后切所有NSObjectdealloc如若标识了的联合执行[[NSNotificationCenter defaultCenter] removeObserver:self],反正多执行了也没问题用的放心!

但如假若成对的,就有另一个问题,万一真正需求注销的地点是跟逻辑有关,那你对象销毁时注销早就晚了,似乎上边KVO中提到的我们做的这层crash防御其实犯错率并不高能及时发现,而及时发现不了的只可以是经过编码规范仍旧人士分别禁用来化解。

“答应你的告白啊!”庄喜喜的小酒窝长睫毛在她巴掌大的小脸上雀跃着。

Thread Conflict(线程争辩)

主导无解的题目,出现之后眨眼之间间懵逼,典型例证就是死锁,异步调用同一对象造成不安全,基本没有防守手段,排查也只可以靠多加log不断复现,然后猜。。。。
但一般只要代码依照正规的正经写也不会那么不难蒙受这问题,但线程争论理论上万一保障UI操作都在主线程,其余都gcd不在主线程上,然后部分必要线程安全的gcd信号量做锁就能够,但不会有人如此写代码,性能和功效那么搞是都要废的,现在都期盼你马上出活那有空那样,这类就足以完全不考虑防御的事了!

陆衔一还平昔不影响过来,他就曾经被旁边这位看起来文静内敛实则话唠的姑娘介绍给半路杀出来的院系导师了。

“石讲师,我是陆衔一的女对象。”

陆衔一再一次对这一个小不点大跌眼镜了,那句话的逻辑是或不是不足了点?一般不都是“xxx是自己的xxx吗?”

现今不是纠结那个的时候,解释清楚才行,陆衔一的思绪后知后觉拉回来,然则已经迟了。

“哦哦哦!我精通的,这些是陆衔一,也是该校的名流!”老教师的一撮小胡子欢悦地抖了一抖,陆衔一嘴角抽搐,这些“也”字被故意强调了,他险些忘了温馨的大叔也是该校知名学生闻风丧胆的上书。

2.

那终究被逼迫中奖了呢,陆衔一遍到宿舍回顾了一整天的碰到,忍俊不禁,只好用“被强迫中奖”来形容了。

老陆是在夜晚十点多打来的对讲机,依据高校音信传出的进程,依据石教师和老陆的基情来猜度,他和庄喜喜前脚离开,那信息应该早就传到了老陆的耳朵里。

那么些点打来电话问八卦,难为他忍了这么久。

“我听说您小子近年来有事态啊!”

“呃……情况稍微突然。”

“三姑娘叫什么名儿,有没有选修我的课?”

陆衔一摊开手掌,他还真不太驾驭他叫什么名字,临走的时候对方在投机的牢笼大笔一挥写下了名字和电话。

“庄喜喜,国文系,跟你的天文八竿子打不着。”陆衔一对着台灯仔细看,心想怪不得她嘴巴那么能说,敢情肚子里都是墨水儿。

“睡呢睡呢!明日带给我看见,你小子终于开窍了!”伴随着老陆爽朗的笑声,陆衔一的男孩突然浮现孩他妈公见儿媳的画面感,他费劲摇了摇头,如故不要将错就错了,今日去解释清楚。

那天早晨,二十三岁的陆衔一辗转难眠,那缘分也是很想获得的,大学四年没有赶上一个让她心动的,那都读研一了,居然来一个碰瓷女对象的,想想也是好笑。

陆衔一枕着胳膊,睁开眼睛毫无睡意,天花板上的白月光一亮一亮的,就像庄喜喜的微笑一样晃人眼,他又两回迎着月色将魔掌的那多少个字看领悟,回想起女孩子欣欣自得的面容,不禁嘴角上扬,她大致是吃可爱多少长度大的,她笑起来怎么那么美观。

3.

庄喜喜上个月被室友拉去算了塔罗牌,神婆指导,只要多去可以磨练情操的地点,缘分放任自流就来了,神婆最终语重心长地叮嘱:缘分急不得,你要等。

庄喜喜从神婆那儿回来将来,研商来商量去,发现可以陶冶情操的地点就唯有教室这么的知识的大洋了。

校园的分寸体育场馆分别接近南南门,就到底直线距离也得步行个十分钟,庄喜喜天天下课直奔体育场馆,不通晓的认为她是多奋进的女学霸。

前前后后加起来,庄喜喜在体育场馆呆了十多天,毫无进展毫无艳遇的气息,就在她即将灰心消沉的时候,陆衔一的身形跃入眼帘,那样一枚气质俱佳的美男子,就连周身都类似散发着金光。

庄喜喜突然想到了袁湘琴看植树时的一句心里对白:全体的星星洒在您的头上。

那儿还等什么吧?矜持是上好的浓眉大眼有的奢侈,她庄喜喜身材娇小,并不浪漫,成绩一般,并不完美,矜持什么的就是浪费和不作为。

于是庄喜喜一路随即陆衔一开头了一天的随行,像个变态侦查员一样在小本本上记录了陆衔一一天的路程,幸运的是,陆衔一这个人并不是来图书馆突击的学渣,他每一日准时到教室报导。

庄喜喜正愁不知晓怎么进攻的时候,机会就那样一差二错地掉在了她的眼前,本来是他准备告白陆衔一的纸条被陆衔一碰掉了,她大费周章,这才正大光明地赖上了男神。

4.

庄喜喜那种猴精儿的人怎么可能让男神跟自己撇清关系啊?何况音信一度以光速传开,她如何也要弄假成真。

于是庄喜喜一不做二不休,课还没起来,她积极跑到陆衔一的大课上坐到陆衔一的边边儿上,包包里各个零食外加防蚊驱虫的利器,以至于周围的同班们纷纭甩来哀怨的目光,同是在探讨院里挣扎的社会青年,凭什么你老牛吃嫩草被供奉到那般地步?

陆衔一忍受不住一旁室友的错综复杂目光,索性教师也还没来,不如把那个自来熟的“女对象”拉出去解释清楚。

“大家谈论呢,庄喜喜同学。”

庄喜喜充耳不闻继续对陆衔一的室友们大献殷勤:“同学同学,我们老陆有劳你们照顾了……”

陆衔一真的是没见过如此上赶着的姑娘,本来还想和和气气,现在不得不生拉硬拽。

只可是好巧不巧,助教拿着茶杯悠闲进来的那一秒,四人推搡的神态不紧令人联想,陆衔一认命地抓牢了庄喜喜的手臂,事已至此还爱戴什么先礼后兵,干脆扛出去好了……

那下整个阶梯教室更是一片起哄声:没悟出冰山陆衔一谈起恋爱来如此生猛,心情四射啊。

陆衔一嘴角抽搐,气的一个字也吐不出来,讲台上的上书虎躯一震,老陆家的男女哪些也恋爱了,可怜自己女儿对她至死不悟……

“你这上着课呢去何方……老陆知道你堕完结那样又得气的一点天不进食……”讲师追上来谆谆教诲,动之以情晓之以理。

“教师,老陆假使真的知道了,估摸得多吃几碗,不信你深夜吃饭的时候跟她说。”

讲解的一撮小胡子抖了三抖,世风日下啊。

“助教不佳意思,大家先走了。”庄喜喜终于有机会说了一句话,陆衔一一个白眼砸过来,她有点后怕了。

5.

“庄喜喜,24钟头之内,你是本人女对象那件事人尽皆知了,你怎么看?”

“那我是否你女对象啊?”庄喜喜仰着脸那叫一个童真。

“当然……不是。”陆衔一愚拙了零点儿三秒。

“那您生什么气?搞天文的那样沉不住气,能体察得好哪个行星?”

陆衔一人生第一遍被人难以置信自己的专业性,怒火中烧,那小不少于人不大,倒是很会折磨人。

她前行一步逼近,大有要把庄喜喜吃掉的气焰,庄喜喜触目惊心小鹿乱撞神志不清……这巨大的心气一切涌上心头,最后唯有一个结实。

那就是色令智昏了。

庄喜喜因为陆衔一的超中距离,心跳加速,那雕刻美男的五官果然是让人神不守舍,反正成不成今日是迟早会有个结实了,陆衔一女对象的名头在那儿,不亲一下岂不是很亏?

于是乎庄喜喜闭着双眼踮着脚就往陆衔一的脸庞吧唧一口,亲完了意识地方有过错,不理对方铜铃一般大的眼镜继续生猛地扑上去,对着可人的嘴巴又啄了两下。

其一剧情陆衔一是越来越搞不懂了,拉出来解释清楚的,几时变成了拉出去恩爱的戏码?

陆衔一干咳一声缓解窘迫,只认为那姑娘的小嘴唇也过于柔软温暖了吧。庄喜喜亲完之后反而糟糕意思起来,又上演了三遍撒腿就跑的剧情。

陆衔一对着仓惶逃窜的背影忍俊不禁,一路体会猝不及防的接吻,进门的一念之差全班哄堂大笑。

老教师扔下粉笔一脸不悦:诶呦喂~你那脸上就不可以擦干净了进来?

这下好了,被庄喜喜狂亲事儿估摸又要变成热点了,陆衔一欲哭无泪。

6.大约一节课刚开端的五分钟,阶梯体育场馆里的学习者早已上马坐不住,什么选题什么课程杂文,枯燥的学术报告哪儿会比得上头条八卦有意思?

陆衔一后知后觉在高校网站上看见庄喜喜和友好热吻的题目,老脸一红总以为有些老牛吃嫩草的怀疑,陆衔一点进来一字一板往下看,除了附上了高清大图还有gif动图,这连着亲了两下或者筋疲力尽的像个傻瓜,他怎么一见到庄喜喜就体现鲁钝和木纳?那是基于一种什么的情义才会有这么的反射?

那课老师讲了什么他一个字也没听进去,反倒是教员那句听腻了的口头禅在脑海中盘旋:实践是印证真理的唯一标准……

那就是说,如何验证心思呢?要怎么执行?

陆衔一埋头冥想了半天也从未答案,心理那种事真是比他考研还要难。

那边小陆纠结困扰,坐在办公室里的老陆跃跃欲试想去看看是哪个人拯救了陆衔一,孙子23岁连孙女的手都没牵过,一度以为是性向有问题,不明白愁的她长了有点根白头发,现在突然有了桃花,仍旧不顾一切的大桃花,老陆激动的差不多睡不着。

想她堂堂一个985该校的博士导师,老来得子本就把这几个“子”看得比命还重,隔壁办公室,隔壁的邻座的办公室,这几个个助教里面子女大多已经结合甚至抱上了大胖外甥,他看着爱戴却也只好努努嘴,陆衔一这小子从小不爱跟女生玩,他一个转业大学教育的劳力平日鼓励她在什么年龄做什么事。

例如十七八岁就该来一遍纯洁的早恋,他不,他无处参预比赛闷在家里捣鼓他老子的天管医学资料,眼看五年过去了,陆衔一照样是不近女色,多少让她略带担忧。

今昔有姑娘死缠烂打上了,他只愿意那姑娘千万不要扬弃。

7.老陆专程去国文系走动了一番,庄喜喜迟到进来,正看见一位身躯凛凛的中年男人和讲课相谈甚欢,猫着腰轻手轻脚尽量不引起注意,没悟出仍旧被授课点名了:庄喜喜,你回复。

庄喜喜那叫一个心虚,她多年来为了堵陆衔一,不了然翘了多少灭绝师太的课,现在算是要被拎出来当典型了。

“你那恋爱谈的什么?”灭绝师太庄重脸,一旁的男人饶有兴致地望过来。

“不如何……”庄喜喜如实回答。

“不怎么?”中年男人率头阵问。

“人家都没怎么理我,是何人说女追男隔层纱的,根本就是隔着沙漠……”

“那……那你也不可能放任,你相对不可以屏弃!”中年男人激动地商议。

“对对对!你你你不要甩掉,只要你追到陆衔一,我那科你借使挂了,我给您开小灶补课。”最终那句话灭绝师太身体前倾小声说到。

庄喜喜不敢相信暗戳戳自己的腰,又奋力保持了心中的沉着,从她们的眼力中看到了诚挚和火热,她没悟出现在的名师已经那样开明并且充满了人情味儿。

“可是老师……”

“怎么怎么了?”

“我刚刚强行亲了陆衔一,我没脸见他了……”庄喜喜眯着眼睛不敢看助教们惊恐的神采。

一阵安静之后,中年男人说:“好样的!我帮你,老李,我随便了哟,我带那女儿走了。”

灭绝师太点点头,庄喜喜全然不知,那眼前走着的莫过于是他最该拍马屁收买的陆衔一的岳丈陆秋人。

8.

“依照自家对陆衔一23年的打听,那孩子吃软不吃硬,你哭给他看。”中年男人说。

“真的?然而我哭起来不为难。”

“那就表情做成功,很委屈,我每一趟有怎么样报告须求让他寻觅资料,动之以情,他都会答应的。”男人表情得意。

“然而她不喜欢自己自己也不可能赖着,我自然就够耍无赖了,今日还耍流氓了……”往事不堪回首。

“何人说的,他喜爱你,更加喜欢。”老陆的嘴角抽搐,那辈子都不是爱撒谎的人,为了外甥也是难为和谐了。

“你怎么领会……”庄喜喜一脸天真。

“我是他爹啊!庄同学,我主持你。”老陆觉得那女儿真的挺好的,除了有些聪明那件事他也是可以容纳的,他陆家基因强大,娶个没多少天资的婆姨也没在怕的。

庄喜喜热情洋溢,追陆衔一的那些心绪又足了,她在男生宿舍门口徘徊来彷徨去,酝酿了稍稍复杂的情怀都未曾排得上用场。

因为……下雨了,电闪雷鸣的地形雨,叫了一声陆衔一的名字,窗口没有其余答复。

雨那么大,她那眼泪再多再猛也是看不清的,庄喜喜总认为是上天的某种暗示:你俩没缘分,别为难了。

庄喜喜一路淋着雨回到宿舍,极其委屈,这可是他的初恋啊,也总算轰轰烈烈极其苦难了。

9.庄喜喜重高烧在校医室连着挂了几拉萨,灭绝师太对此无比同情惋惜,让她可以疗伤,尽快从失恋的阴暗中走出去。

有关陆家的父子俩人,老陆干坐在办公室里着急,听闻三姑娘已经好些天没去找陆衔一,多少有些扼腕叹息。而故事的主人公陆衔一同学,在体育场馆等不到庄喜喜,又跑去体育场馆打算偶遇,没悟出庄喜喜人间蒸发根本没了踪影。

总认为被女儿戏耍了一次,心里是又气又恨,又想起庄喜喜写在掌心的联系方式,早就被洗掉了。

陆衔一腆着小脸跑到老陆的办公求接济:“老陆……能无法帮我问问国文系庄喜喜的联系电话。”

陆秋人抖先导拨通了国文系相关讲解的电话机:“喂喂喂!你帮我找一个学员的电话,庄喜喜,是老李的学童,没怎么……不是否,那孩子跟自己孙子处对象,闹脾气了,我那老头子想偷偷当和事佬……好好好,一定请你吃酒!”

陆衔一一个头四个大,那都什么跟什么……

电话号码几秒钟过后发过来了,陆衔一纠结了半天,如故他大叔拨通了号码。

“庄喜喜同学,我是陆衔一的四叔……”

“您好,我喜喜的室友。。”

“庄同学不便于接电话吗?”

“他被你的混账外甥伤透了心,现在卧病在床……”

“你说怎么?”陆衔一一把夺过电话。

“她在校医室。”

陆衔一撂下机子一起狂奔,老陆披露老二叔的爱心笑容,那事儿,成了!

10.

陆衔一刚踏进校医室的大门,只听一声长啸吓飞了窗外栖息的麻将,护师在第两遍扎针的前一秒,庄喜喜泪流满面地求饶:“护师四妹,我不扎针了,我好了,我想回家。”

“你那婴孩肥,白胖白胖的胳膊确实也难找,再来三次哟,不行即便了。”

“不了真不了,我那手都青成这么了。”庄喜喜求饶。

“乖,再扎四次。”陆衔一走过来,庄喜喜睁大眼睛不敢相信。

“医务人员,我是否病入膏肓出现幻觉了?”庄喜喜泪眼婆娑。

“没有没有,确实有个帅哥让您乖一点。”

“陆衔一您怎么会来?”

“你生病了怎么不告知自己?”

“你又不是医师……”

“你那纠缠了自己几天突然没影子了,我来认同一下死活。”陆衔一嘴硬。

庄喜喜被戳中了隐情,再添加胸口痛不退心里悲伤,下一秒嚎啕大哭泪如雨下。

“你哭的也太丑了吗。”

“啊!!!”庄喜喜哭声更猛。

“美美美,梨花带雨。”庄喜喜须臾间终止泪腺。

“那您来,是干嘛来的?”

“庄同学,我来跟你谈谈。”

“谈怎样?你又要拒绝我四回?”话音刚落,一声尖叫再度打破云霄,护师大姨子一脸欣慰。

“我来跟你谈恋爱。”

相关文章