QCon 北京 - 移动开发

@robinlu 的 High Quality iOS Development.

内存管理中的引用计数,Ownership 的概念,以及 Autorelease 的使用,这些都快被讲烂了。

但里面提到的 implicit ownership 以前没怎么注意过:

NSTimer, Delayed performance of selector, Thread, IBOutlet

另外提到的 Circular Reference,使用引用计数来进行内存管理很容易出现环引用的场景,比如有一个父视图包含一个子视图,则 retain 子视图,然而子视图又需要知道自己的父视图是谁,则需要 retain 主视图,于是就出现了循环,这样因为相互依赖,内存始终是得不到释放的。

这时就有一个弱引用 (Weak reference) 的概念,即子视图只持有父视图的指针,cocoa 里面很多都机制都采用了弱引用,比如很常见的 delegate.

讲到 Clang Static Analyzer 的时候,看到竟然除了内存泄露等错误外,还能查出逻辑错误,在 if 嵌套且多的情况下极为适用。虽然有神器,还是对自己好点,毕竟写那样的挺费脑细胞的,嵌套到 2 层就得了,别再深了。

Holly Lee 的利用 iOS 新特性进行开发中的 Block

一直以为是在 objc runtime 层面实现的 closure 或者 lambda,才发现原来是直接基于 C 语言增强的。

1
2
3
4
5
6
7
8
9
10
11
12
13
int result = ^(int a) {return a*a;} (5);

typedef void (^blockWithString)(char*);
char *greeting = “hello”;
blockWithString b = ^(char* place){ printf("%s %s\n", greeting, place); };
greeting = "goodbye";
b("world"); // prints "hello world\n"

__block char *mutable_greeting = "hello";
c = ^{ mutable_greeting = "goodbye"; };
printf("%s", mutable_greeting); // -> "hello"
c();
printf("%s", mutable_greeting); // -> "goodbye"

看起来很像是函数指针,只是把 * 换成了 ^.

Block 最大的特点就是,里面的局部变量只是该变量进入 Block 时刻的快照,以后任何时刻,该变量被更改与否跟整个 Block 没有关系,天然的加锁啊。其实 Block 的动机就是来源于 GCD (Grand Central Dispatch),这个功能是为了在同步 (Cocurrency) 下有更好的效率。据说有超过 100 个 Apple API 都已经使用了 Block。

高焕堂高老师整场的安卓理念流讲座

非常精彩,举例形象,幽默,都 56 岁了还在追新,还在写代码,真是码农学习的好榜样那。

高老的主张是 iOS 拼应用,Android 拼底层。因为 Android 本身是十分开放的,可以轻而易举的对底层进行更改,从而才能造就百花齐放,产品差异化化的局面。通过差异化的增值获利途径,是推动 Android 拓展和技术提升的关键环节。

他说:

  • Android 很烂,每一个模块都没怎么测试,但那么多模块组合起来竟然还能用;
  • 没钱就改版,改版就有钱;
  • 跨平台是乌托邦;
  • 他不看重用户体验,他举了个例子,比如嫁女儿,别人不说你女儿值得拥有,给你说用户体验真好;
  • 企业是坏女朋友,跟他好,赚不到钱,硬件是大老婆,要跟大老婆好,然后赚坏女朋友的钱。
  • 实践的不赚钱,定义接口不干活的赚钱;

不过搞笑归搞笑,但有一点是很有道理的,就是写基类的赚钱,写 App 的不赚钱。

搞硬件,然后用 C 做驱动,最后提供基类给企业,让其做 App,然后就赚大钱了,因为底层把握在自己手中。

这和 Apple 的策略极为一致!

他把 App 比喻成塞外,Framework API 比喻成万里长城,JNI API 比喻成北京城,HAL API 比喻成紫禁城,然后里面住着慈禧太后。每一层屏障,都是里面的人为保持自身利益所设立的,专注开发底层硬件和驱动才能成为 Android 手机大赢家。

Han Chao 的 Android 对 Linux 内核的改造及其影响

从 Linux 纯技术的角度来看 Android。

比如为了满足硬件上不想开源的需要的硬件抽象层,巧妙的使用 /dev/binder 为用户层程序提供了 IPC 支持,以及采用类似方法(MISC 设备) 实现的 Logger,Ashmen, Alarm, pmem 等。

最后提到争议中的电源管理,Linux 的电源管理分为两级,在 CPU idle 的时候,会给所有的设备发 suspend 消息,然后设备依次休眠,最后 CPU 停转,有任务时,CPU 先开工,然后发 resume 消息给各个设备,唤醒机器。

Android 为了满足即使 CPU 有少量任务时,也可以对设备进行休眠,在 suspend 之上提供了 early_suspend 机制,在 resume 之上提供了 late_resume,这两层都是在用户空间实现的,也就代表着用户空间可以干预,传统 Linux 用户空间是不可以干预的。

但这样改的代价是所有相关的驱动,都要加上这样的处理,Linux 社区不会答应的。

最后总结了三句:

  • Android 和 Linux 都是很纯粹的技术
  • Android 很遵循 Linux 的理念和原则
  • Android 不能代表 Linux 标准