1、NSSetUncaughtExceptionHandler注册捕获错误无法调用
2、自定义提示宏
3、frame和bounds
4、Swift中inout和C/C++中指针/引用的区别
5、获取UICollectionView的高度
NSSetUncaughtExceptionHandler注册捕获错误无法调用
原因是老代码中集成了友盟分析,并且没有关闭友盟错误收集机制。友盟内部的错误收集方式也是采用这个方式,所以自己注册的错误处理函数被友盟覆盖,因此不会被执行。
同理,多种第三方的错误日志应该是不能同时实现捕获的。也是看到了友盟的文件夹才想到这点,stackoverflow上面说的都不是很符合这种情况。
自动提示宏
什么情况下需要用到自动提示宏
- 使用KVO,KVC时使用(归档的时候也可以使用,这样就不用设置一堆宏了)
1 | keyPath(objc, keyPath) @(((void)objc.keyPath, |
frame和bounds
今天要实现图片浏览器中的一个需求,然后就遇到了这个问题,需要明确两者之间的区别。后来google了一些资料,有一篇UIScrollView原理解决了我的问题。
里面对于我最重要的就是这句话了:
1 | This is, in fact, exactly how a scroll view works when you set its contentOffset property: it changes the origin of the scroll view’s bounds |
所以UIScrollView的偏移是通过设置bounds的origin来实现的。看了一些MWPhotoBrowser源码也确实使用UIScrollView的bounds来改变对应子视图的frame:
1 | - (void)layoutSubviews { |
然后忽然又想到了另一个问题,在这里记录备忘:CGAffineTransform实际改变的是bounds
。
iOS-Core-Animation-Advanced-Techniques中有一句:
1 | frame并不是一个非常清晰的属性,它其实是一个虚拟属性,是根据bounds,position和transform计算而来 |
所以改变视图的transform,实际上是改变其layer的bounds。苹果相关库头文件中也有这么一句话:
1 | extension UIView { |
Swift中inout和C/C++中指针/引用的区别
首先明确概念:
- inout是passed-in-passed-back形式
- C/C++中是引用形式
关于inout关键字,Swift的一些官方文档给出了很详细的一些回答,如下:
从这么多篇幅的解释中,可以很清楚地知道inout的作用方式:
1、函数被调用,拷贝实参
2、拷贝在函数中被修改
3、函数返回,拷贝被赋给源参
并且一旦相应的函数返回,上面步骤就结束了,剩下的操作便无法改变源参。以下代码段都不会改变传入的参数:
1 | /// 1 |
在Swift中,如果想改变上面代码段传入的参数,可以使用UnsafeMutablePointer指针(只是例子,实际并不推荐这么做,这种方式是不安全的):
1 | /// 1 |
获取UICollectionView的高度
UICollectionView的高度通过其布局属性,也就是以下属性进行获取:
1 | @property (nonatomic, strong) UICollectionViewLayout *collectionViewLayout; |
布局属性有个获取Size的方法:
1 | - (CGSize)collectionViewContentSize; |
需要注意的是这个方法UICollectionViewLayout的子类必须进行重写(流水布局已经重写了)。
这样就可以在UICollectionView的子类中重写sizeToFit方法进行自适应了:
1 | - (void)sizeToFit { |
同理,如果是一个视图的子视图,也可以同时设置父视图的frame:
1 | - (void)sizeToFit { |
这样以来就可以很方便地对UICollectionView进行一些操作了,比如在UITableView中嵌入一个流水布局的UICollectionView就可以利用上面的方法获取其实际高度。实际业务的应用