最近在写论文阶段, 没有足够的精力来写技术分享, 再此说声抱歉, 不过我也会尽力挤出时间不定期为大家更新一些干货的!! 请大家继续关注!!
POP全屏转场
好了, 今天要分享的是5行代码实现全屏POP转场动画, 众所周知,iOS7后导航控制器默认自带了侧滑功能,当用户在界面的左边滑动的时候,就会有侧滑功能。导航控制器的view自带了滑动手势,只不过手势的触发范围只能在左边。当用户在界面左边拖动,就会触发滑动手势方法,并且有滑动返回功能,说明系统手势触发的方法已经实现了滑动返回功能
1 2 3 4 5 6 7 8 9 10 11 12 13 |
- (void)viewDidLoad { [super viewDidLoad]; id target = self.interactivePopGestureRecognizer.delegate; UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:target action:@selector(handleNavigationTransition:)]; pan.delegate = self; [self.view addGestureRecognizer:pan]; [self.interactivePopGestureRecognizer setEnabled:NO]; } - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { return self.childViewControllers.count == 1 ? NO : YES; } |
我们只需要在SQNavigationController中添加一个全屏的滑动手势,调用系统自带滑动手势的target的action方法,利用系统实现的滑动返回功能,加上自己全屏滑动手势,就有全屏滑动功能了。
显示效果
Runtime 预防数组越界
我刚学习编程的时候有老师告诉我, 大约有90%的Crash来自于数组越界, 那如果解决了数组越界那就能够屏蔽90%的Crash 是不是很厉害!! 哈哈哈~~~ 但是我们怎么能够屏蔽越界呢??
大家都知道在数组越界就是objectAtIndex:
这个方法的index
超过了数组的count
然后就无情的Crash了, 最为粗暴的解决方法是在每一次objectAtIndex:
时做下if判断, 的确有这么个习惯非常好,但是人总有遗忘的时候, 项目那么大不可能每次我都写把… 这时 我们想到了第二个办法 就是在NSArray的分类中写一个safeObjectAtIndex:
以后所有调用数组下标,都使用这个方法, 期初看这的确是一个办法, 不过如果是在项目中期, 我怎么保证前面的都有使用这个方法呢? 还有如果使用array[index]
这种coding suger的访问 根本就不可控啊!! 于是我们来学习最终的解决方案Runtime;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
+ (void)load { SEL safeSel = @selector(safeObjectAtIndex:); SEL unsafeSel = @selector(objectAtIndex:); Class class = NSClassFromString(@"__NSArrayI"); Method safeMethod = class_getInstanceMethod(class, safeSel); Method unsafeMethod = class_getInstanceMethod(class, unsafeSel); method_exchangeImplementations(unsafeMethod, safeMethod); } - (id)safeObjectAtIndex:(NSUInteger)index { if (index > (self.count - 1)) { NSAssert(NO, @"beyond the boundary"); return nil; } else { return [self safeObjectAtIndex:index]; } } |
Runtime也就是运行时, 是OC中消息机制msgSend
的核心, 但是要讲Runtime真的涉及到的知识点太多, 一般实际应用场景有, 模型转字典, 分类加属性, 动态创建和获取等,JSPatch热修复也是基于Runtime实现的,今天我所分享个大家的用法是交换两个方法的实现来防止数组越界造成的崩溃!!
我们来分析上面的代码, 其实也没有什么好说的…
+ (void)load
方法是在创建分类的时候系统会自动调用的方法
SEL unsafeSel = @selector(objectAtIndex:)
objc_selector结构体的详细定义没有在头文件中找到。方法的selector用于表示运行时方 法的名字。Objective-C在编译时,会依据每一个方法的名字、参数序列,生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL。
Method unsafeMethod = class_getInstanceMethod(class, unsafeSel)
使用runtime方法拿到类中的方法
method_exchangeImplementations
交换SEL对应的IMP实现
这样 我们就轻松愉快的防止了90%的Crash 是不是很牛逼!!!!
进一步联系我
好了 今天的分享也就结束了, 最近想换个环境找个新工作, 地点在上海, 有志同道合的朋友可以发我私信进一步联系!!
github 下载地址!!!
点击下方链接跳转!!