Block 调用检查

前言 如何确保一个传递给别人的 Block 被调用过,是一个一直困扰我的问题,因为 Block 作为 iOS 的一种回调机制,它可以像函数一样马上被调用,也可以像对象一样被持有、被传递、被释放,并在将来的某个时候被调用。有些时候我们传出去的 Block 必须被调用一次,否则会处于一种不确定的状态而导致程序无法继续,或者出错。例如,之前一篇文章《一种 App 内路由系统的设计》中的路由注册方式, »

讯飞输入法 iOS 版的一个 Bug

一个正常的 UITextField,当有中文后跟一个英文字母时,删除这个英文字母,收不到文字变化的回调。 UITextField *textField = ...; [textField addTarget:self action:@selector(onTextChanged:) forControlEvents:UIControlEventEditingChanged]; 然后又尝试监听通知,也不行。暂时无解,搜狗、百度等键盘没有发现此问题。 UITextField *textField = ...; [[NSNotificationCenter defaultCenter] addObserver:self »

PHAsset 获取图片高宽的 Bug

最近遇到一个在 App 中打开相册 Crash 的问题,但是我们无法复现,于是找用户要到了她要上传的图片的原图,原图是一张微博等平台上常见的超长图片。现在不少专业的博主为了排版方便及全平台统一,都会使用一整张长图来发内容,而不是用图文混排的方式。 图片导入到相册后发现的确会 Crash,于是单步跟进,发现这张图片高度居然是 18446744073709519761!很明显不正常,因为在电脑上查看图片高度为 33681,如果 App 认为它高度是那么多,就会照那个大小去申请内存,不 Crash 才怪。 »

一种 App 内路由系统的设计

本文仅探讨怎样才是路由系统该有的设计,并不涉及具体实现 App 发展到一定程度时,页面越来越多,工程越来越大,合作开发的人也越来越多,这时就可能需要引入路由系统(当然,从项目一开始启动就接入路由是最好不过了)。路由系统提供了一种简单的方式,让用户在不同页面间浏览时就像在浏览器中访问网页一样,一个地址对应一个完整内容的页面(一般使用 RESTful 的风格),如: Foo://users/nickname,打开用户页面 Foo://products/xxxx,打开商品页面 Foo: »

一种组件化的 Table View 的实现

背景 最近在做一个项目时,需要实现一些列表界面,总体上是上下滚动的,中间的部分段有可以横滚的,有一个个小标签式的,也有可循环滚动的焦点图的……且类似的界面大量出现,并随机组合。可以参照网易云音乐,早期版本的蘑菇街,小红书等等。 按以往的想法是,继承 UITableViewController 然后分多个 section,所有的数据与点击都在一个 VC 中完成。如果全是占满行的 Cell,勉强可以接受,但很快你会发现,你的代码变得庞大而臃肿,且不可维护。 »

如何优雅地编写 iOS 第三方库

iOS 经过八年多的发展,已经涌现出诸多优秀的第三方库,但怎样才算是优雅?总体来说,AFNetworking 就十分优雅,而 GPUImage 就只是可用,而不算优雅。编写优雅的第三方库,就像制作一件精美的艺术品一样,过程让人沉醉,结果令人赏心悦目。否则就是单纯的代码堆积与功能实现,过程像搬砖,完成后也没有成就感。下面就本人的一点经验,分享下如何优雅地封装第三方库。 命名 好的命名规则是一个成功的第三库的开始,然而现实中很许多人随性命名,导致沟通成本上升。事实上命名问题上,苹果有其官方统一的标准, »