iOSCon China 2012 系列报道——技术篇

  • 丁雪丰

2012 年 3 月 27 日

话题:语言 & 开发

3 月 25 日,由多个社区联合主办的iOSCon China 2012大会在上海及多个分会场(北京、杭州、武汉、广州、澳大利亚)顺利召开,现场及线上直播的总参与人数超过 800 人,多位国内知名的 iOS 开发者就移动互联网的发展趋势、产品设计以及开发技巧等诸多话题做了精彩分享。

既然是 iOS 开发者的大会,肯定少不了技术方面的话题。iOS 第一个输入法iCosta for iPhone以及RockPlayer for Android的主要开发者之一李亮(@holly_lee)在他的主题演讲中引用了大量数字分析了各个厂商、设备、系统以及地区的占有量,随后大致介绍了如何选择移动应用开发的技术路线:

  • 操作系统。关注系统本的能力,是否支持多任务、是否支持后台执行,操作系统是否有限制,在安全性和隐私保护上表现如何。
  • 设备本身。关注设备的计算能力、图形能力、各种数据采集设备、各种传感器、分辨率、键盘以及 CPU 指令集的差异。Android 设备厂商众多,不确定性也多,而 iOS 设备规格比较统一。
  • 云端服务。云端能够提供的服务,带宽如何,需要自己搭建还是利用现有服务?
  • 平台。即平台的市场比率,成熟度、稳定性,是否有成熟的分发方式和支付方式。
  • Native 应用还是 Web 应用?两者各有优劣,比如本地应用体验稍好,两者会长期共存。
  • 跨平台。是否考虑使用现有的跨平台方案,例如PhoneGap
  • 用户体验。这点现在越来越重要了,应用必须具备良好的用户体验,不能花哨,不能喧宾夺主。

来自盛大创新院的孔详波(@ventrua)为大家分享了在 iOS 开发过程中如何进行调试,他的内容让一些在场的听众表示能将调试做到这种地步,令人佩服。在介绍了 iOS 应用的启动过程之后,孔详波罗列了一些他所常用的工具:

名称 用途
file 确定文件类型
strings 从二进制文件中查找某个字符串
otool 查看程序使用的动态链接库
class-dump 分析 Mach-O 文件,查看 Objective-C 的运行时信息,例如头文件信息
nm 显示符号表中的名字

此外,针对 Xcode 项目的编译,除了会用到 xcodebuild,还有 gcc、clang 这样的编译器,提取二进制符号的 dsymutil,进行代码签名的 codesign,打包发布的 PackageApplication 等大量工具。

分析代码时,分为静态分析与动态分析两部分。静态分析可以选择LLVMClang Static Analyzer。动态分析则主要以日志输出为主,在输出日志时有一定的技巧,例如,使用系统提供的预定义宏,如 __func__ 、__LINE__、__FILE__;对标准的输出进行重定向;对日志输出做条件编译,调试时输出,在正式发布时不输出。通过 iPhone 配置实用工具可以看到系统及第三方应用的日志,在应用发布之后,设备连接 iTunes 后会同步一些 Crash Reports 到服务器上,这时开发者也能获取到这些信息。

如果遇到了 UncaughtException 也不用慌张,一般遇到 EXC_BAD_ACCESS 这种和操作系统相关的内存错误,系统会返回 SIGBUS 或 SIGSEGV BSD 信号,仔细分析总能找到原因;而 SIGABRT 这样的异常通常不会像前者那么“底层”,可能是数组越界之类的问题。他还推荐了一篇文章《Handling unhandled exceptions and signals》,其中给出了一个处理异常的范例项目

在调试过程中,Xcode 提供了很多有用的功能,例如 Run sysctl.app 中的 Enable Zombie Objects 可以用来查看僵尸对象;Debug Workflow 中的 Show Disassembly When Debugging 甚至还能显示汇编代码。XCode 中提供了两种类型的断点——Exception Breakpoint 和 Symbolic Breakpoint,可以根据需要进行选择,调试区域内可以看到断点的堆栈信息。还有最近兴起的、苹果资助的调试工具LLDB,具备速度快、高效、准确、可扩展、可重用等诸多优点于一身。孔详波建议大家紧跟技术发展,GDB 固然好用,但最好还是能使用新的工具和功能。当有人对 LLDB 不支持 3.0 这样的旧系统提出质疑时,他认为不能因为这些原因就对 LLDB 心存戒备,还是应该有所尝试,而且仅支持 3.0 的设备的用户也未必就是你的主要目标用户。

大众点评的移动研发首席工程师屠毅敏(mmin18)的演讲《iOS 应用开发最佳实践》是整个大会的最后一场主题演讲。开篇他就指出如果精力有限,不要钻牛角尖,把精力放在用户看得到的地方,花大力改进一个单例的写法,用户未必能体会到。

策划一款产品时,不要只想着做平台,不要想着如何整合他人的资源;要让用户一眼就能明白这个应用是做什么的,尤其是产品的名字和图标是很重要的。设计时,一定要记住图标是最重要的 UI 元素,一定要在真实的设备下体验运行的效果,开发与设计是一个不断迭代的过程。

该演讲的重点是开发中的最佳实践。屠毅敏谈到了苹果力推的 MVC 框架,虽然看起来很美,一旦项目大了,难免会有一些混乱,因此在开发时要尽量避免横向的交互,例如同级的控制器不能直接相互调用。iPhone 的屏幕大小未必就是固定的,偶尔在显示时下面会少掉一条,可能是 20 像素,遇到这种情况,可以在 Interface Builder 里设置 Autosizing 进行解决。针对键盘事件,iOS 给了开发者很大的自由度,比如键盘的高度不是固定的,键盘可以跟随滚动条移动等等,他提供了一个范例,希望有更多的人能够协助一起进行完善。此外还提到了一些小技巧:

  • 代码中多使用 property,少声明成员变量
  • 使用 () 作为 Category,而不是 (Private) 的 Category
  • dealloc 写在 @synthesize 后面,一一对应,避免出错
  • init 和 dealloc 中要避免副作用,直接置 null 可能会引起一些莫名其妙的问题
  • 赋值时先判断下可能会让人觉得麻烦,但不这么做又可能会有问题,可以用 [foo autorelease],性能方面的影响其实不大
  • viewDidLoad 可能会被调用多次,而 viewDidUnload 可能并不会被调用到
  • 使用 NSNotificationCenter 时,避免直接 removeObserver:self,这样可能会把父类注册的东西都 remove 掉

新浪微博和大众点评的应用都采用了 Native 与 Web 结合的开发方式,屠毅敏认为采用 Web 方式能够实现快速开发、快速迭代,有很强的灵活性,并且能跨平台、跨版本,应用可以先从 Web 起步,逐渐迁移到 Native 上。在基于 URL 的应用中,应用能注册自己的 URL,实现不同应用的互相调用(比如支付宝安全支付),这样的调用方式更加直观,还可以看到 URL 栈,统计用户行为。在重 Web 轻 Native 的应用中,还需要使用 JavaScript Bridge,Web 调用 Native 时采用 URL Bridge,Native 调用 Web 时则是 JS 注入。

网络速度也是一个重要的因素,每秒对人均 PV 的影响是 15%,应该尽量将响应时间控制在 4 秒以下。对于小数据量传输而言,2G 和 3G 的区别并不大,响应速度才是关键。尽量在同一时间段内、在一个 HTTP 请求中传输所有数据,充分利用移动连接“预热”后的那段时间。

说到参考资料,多位嘉宾都说苹果的官方文档就是最好的学习材料,有能力的话最好能够阅读英文的材料。另外可以关注WWDC所放出的大会资料,从中可以学习到很多东西。

如果您对 iOS 开发及本次大会的内容感兴趣,主办方会在大会结束后整理并提供各位嘉宾的演讲视频及讲稿,请访问大会官网,也可以关注其官方微博(@iOSConCN)。

语言 & 开发