信息和学习

2017-5-30 评论(7) 分类:随记

最近上下班路上还在听罗辑思维,虽然我本人很不喜欢罗胖,但他的节目还是会听听。每次听都会听到一些逻辑错误想吐槽,缺啥喊啥,罗辑思维很缺逻辑,不过仔细想想,每天都要出节目并且拼上一些观点和结论,如果每个观点结论都要求逻辑严谨是比较难,可以理解。

一时举不出逻辑错误的具体例子,因为每天听过后基本上都忘了,罗辑思维从以前的一周四十多分钟变成现在的每天八分钟,其中一个原因是说四十多分钟的节目很长很重很多人听了记不住,所以改成八分钟以内,这个逻辑也是挺搞的,四十分钟讲一个话题记不住,八分钟反而能记得住?实际上都记不住,可能跟各人记性好坏有差异,但更多的是大脑机制就不允许你听一遍就记住,如果大脑把每天所见所闻都记住,那就太多了,信息爆炸。只有那些经过脑子不断思考,重复输入输出的信息才会被记住,才能转化成自己的知识。

轻轻松松听人讲讲故事和观点,只是当下接收一下信息,如果没有后续自行琢磨重复思考,实际上留不下什么东西。罗辑思维这种通过加工后的信息输入会让人感觉很有营养很有效率,实际上信息输入是学习中最简单也是作用最小的部分,真正起作用的是自己大脑对信息的加工思考和输出的过程。回想读书时期,知道一条原理公式是不是很容易?大概几分钟就觉得已经理解了,实际做题要用到这条原理公式时,才发现并不容易,需要反复练习不断通过自己大脑的再加工才能掌握和理解。这跟成功学也挺像的,其他人总结的观点技巧只是信息,输入这些信息是最简单也是最无用的,最困难和最有用的是实践。听节目看文章输入信息只是让你知道有这么个事,完成了学习的一小步,后续一大步还得靠自己。

罗辑思维和得到 APP 标榜终身学习,但产品上并没有让用户学习,并没有任何让需要用户动脑思考的产品特性,只是在单方面提供一些信息,你要是觉得每天轻轻松松不怎么动脑听听电台就是学习,就能获得知识上一个档次,就跟看成功学觉得自己能成功,已经跟成功人事思维在一个档次一样。

得到的产品经理们当然明白这些,只是用户都是懒的,如果真要做到像标榜那样的帮助人终身学习,做一些产品特性帮助用户在思考,对输入的信息再加工再输出,这样产品的受众就很小了,永远只有少部分人愿意去思考和真正学习,大部分人不想动脑,而且是不想动脑不想花时间还想学到知识,得到迎合了这个需求,提供了省时间获取信息的方式,让人轻松获得信息并自以为在学习。实际上得到是提供了挺多高质量信息,是个不错的信息源,但他不告诉你我只是提供跟以前商业杂志一样的信息,而是吹嘘能帮助你终身学习,混淆概念,迎合现代人的焦虑和懒惰,挺鸡贼的。

四月

2017-4-30 评论(9) 分类:生活

这个月比较忙,博客拖到最后一天,不知道写啥,写写近况和感受吧。

这个月换工作换城市,从腾讯到蚂蚁金服,从广州到杭州,距我上次回腾讯已经三年,回想起来还是要特别感谢当时给我机会回去的老大们,三年里有很多成长,有很多 nice 靠谱的同事们,也很幸运有微信读书这样的项目,小而美的团队,做自己喜欢的产品,离开时还真是挺舍不得,希望微信读书越来越好。

为什么要离开呢,原因很多,还是想多尝试些不同的东西,在腾讯顺顺利利,舒舒服服,轻车熟路,有点遇到了成长瓶颈,想换个环境见识一下,趁现在还能经得起折腾,另外一辈子住一个城市好像也比较闷,从大学开始来广州接近10年了,换个城市试试也不差,虽然搬迁代价很大。

为什么从一个大公司到另一个大公司,其实大公司之间的差别很大,至少腾讯跟阿里的差别是巨大的,做事的方式不一样,公司大了公司文化这种东西就不是虚的了,是时刻存在并影响着日常的做事方式的,体验学习适应中。

来杭州三个星期,说说三个印象。

1.旅游生活气息浓

这边可以游玩的地方太多了,在老同学的带领下夜游灵隐寺和大运河,大运河旁都开发得跟乌镇那样,团建去了西溪湿地,还有大量旅游景点没去,不止是杭州,听同事说周边还有各种景点,会经常发现小时候读的古诗里的地点,像苏州的“姑苏城外寒山寺”,要是在杭州工作不忙的话,每个周末都像在旅游,幸福感还挺高的,希望后面有周末时间。

2.交通差

在这边开车我都震惊了,红绿灯之多令人发指,在广州我比较讨厌新港西路,10公里就有十几个红绿灯,觉得没天理,但在杭州5公里就能有十几个红绿灯,可怕。另外道路规则还挺复杂,有的左转道在左边有的在右边,有的红灯可以右转有的不行,路也很窄,单行道挺多,战战兢兢,还试过在西湖广场调个头调了半个钟,醉了。不过杭州道路对单车电动车倒挺友好,于是我现在是开电动车上下班。

3.前途光明

看到各种新大楼,科技新区,感觉互联网行业繁荣度比广州好太多,办G20城市面貌有很多改进,城市规划好,多中心,不像广州一样集中在单个中心,据说后续六七条地铁会同时开通,后面还要办亚运会,生机勃勃,人才净流入,城市前景一片光明,杭州去年房价涨得不像样,感觉要不是限购,今年还会继续大涨。

另外杭州似乎雾霾是比广州严重的,不过来的这三周里除了第一天雾和霾比较重,其他时候空气倒还不错。现在应该是气温最好的时候,据说杭州冬天湿冷,夏天又热到40度,比广州还可怕,到时体验一下。

iOS App 签名的原理

2017-3-13 评论(28) 分类:技术文章

iOS 签名机制挺复杂,各种证书,Provisioning Profile,entitlements,CertificateSigningRequest,p12,AppID,概念一堆,也很容易出错,本文尝试从原理出发,一步步推出为什么会有这么多概念,希望能有助于理解 iOS App 签名的原理和流程。

目的

先来看看苹果的签名机制是为了做什么。在 iOS 出来之前,在主流操作系统(Mac/Windows/Linux)上开发和运行软件是不需要签名的,软件随便从哪里下载都能运行,导致平台对第三方软件难以控制,盗版流行。苹果希望解决这样的问题,在 iOS 平台对第三方 APP 有绝对的控制权,一定要保证每一个安装到 iOS 上的 APP 都是经过苹果官方允许的,怎样保证呢?就是通过签名机制。

非对称加密

通常我们说的签名就是数字签名,它是基于非对称加密算法实现的。对称加密是通过同一份密钥加密和解密数据,而非对称加密则有两份密钥,分别是公钥和私钥,用公钥加密的数据,要用私钥才能解密,用私钥加密的数据,要用公钥才能解密。

简单说一下常用的非对称加密算法 RSA 的数学原理,理解简单的数学原理,就可以理解非对称加密是怎么做到的,为什么会是安全的:

  1. 选两个质数 p 和 q,相乘得出一个大整数n,例如 p = 61,q = 53,n = pq = 3233
  2. 选 1-n 间的随便一个质数e,例如 e = 17
  3. 经过一系列数学公式,算出一个数字 d,满足:
    a.通过 n 和 e 这两个数据一组数据进行数学运算后,可以通过 n 和 d 去反解运算,反过来也可以。
    b.如果只知道 n 和 e,要推导出 d,需要知道 p 和 q,也就是要需要把 n 因数分解。

上述的 (n,e) 这两个数据在一起就是公钥,(n,d) 这两个数据就是私钥,满足用私钥加密,公钥解密,或反过来公钥加密,私钥解密,也满足在只暴露公钥 (只知道 n 和 e)的情况下,要推导出私钥 (n,d),需要把大整数 n 因数分解。目前因数分解只能靠暴力穷举,而 n 数字越大,越难以用穷举计算出因数 p 和 q,也就越安全,当 n 大到二进制 1024 位或 2048 位时,以目前技术要破解几乎不可能,所以非常安全。

若对数字 d 是怎样计算出来的感兴趣,可以详读这两篇文章:RSA 算法原理(一)(二)

数字签名

现在知道了有非对称加密这东西,那数字签名是怎么回事呢?

数字签名的作用是我对某一份数据打个标记,表示我认可了这份数据(签了个名),然后我发送给其他人,其他人可以知道这份数据是经过我认证的,数据没有被篡改过。

有了上述非对称加密算法,就可以实现这个需求:

(更多…)

关于苹果警告

2017-3-9 评论(35) 分类:互联网

昨天早上 iOS 开发者们陆续收到苹果邮件,警告去掉动态下发功能,覆盖面很广,内容没有明确指示是什么库,导致大家各种猜测。

其实上周已经有少量用户收到苹果这份警告邮件,当时还以为是特例,现在看来是在灰度测试扫描代码,可见这事苹果应该讨论已久,并专门排期开发测试了扫描程序,直到昨天才正式上线。

从各方信息看起来,很不幸主要禁的还是 JSPatch / wax/ rollout 这样的热修复框架,特点是可以通过 JS 脚本调用和替换任意 OC 方法,而像 React Native/ 小程序这样用 JS 做功能的暂时不受影响,Weex 不确定,至于其他库像 AFNetworking / SDWebimage 用到那几个接口的,应该只是误伤。

根据苹果要求,收到警告的同学只需要在下次提交版本时去掉相关框架就可以,没有时间期限,目前也不会强制下架。

为什么

苹果为什么这么做呢?苹果对热修复一直以来的态度都是不赞同也不拒绝,JSPatch 本身也并没有违反开发者条例,而且 JSPatch 大多数都用于修复 bug,提升 iOS 平台 App 的质量,对苹果也是件好事,为什么要禁?猜测原因有两点:可控和安全。

可控

苹果一贯作风是让所有事情可控,开发者能用什么不能用什么都尽量在自己的控制范围内。大多数人使用 JSPatch 修复 bug,或者弄一些临时运营的小功能配置,这些没有问题,但总会有少数用户使用 JSPatch 去调用私有API做些事,这是苹果不可控的,也无法知道有多少人这样做了。

不过其实在代码这块苹果其实一直可控程度有限,他会在提交时扫描你有没有用某些私有方法,但只要你对这些私有方法调用做一些变化,加解密字符串拼接什么的,就能绕过扫描,再通过后台配置调用,是一样的。JSPatch 只是让调用私有 API 变得成本更低更方便点而已,可控这里只是个小理由。

安全

去年 FireEye 分析了使用 JSPatch 的安全问题,当时我也写文章回应了,再复述一下,主要安全风险有三点:

  1. 开发者自己本身对 APP 下发恶意代码。
  2. 开发者没有做好加密传输和校验。
  3. 开发者接入的SDK里接入了JSPatch,SDK 作者可以对这些 APP 下发恶意脚本。

第一点其实不算安全风险,因为开发者自己有恶意的话完全不需要借助 JSPatch。

第二点大多数用户使用 JSPatch 时都做好了非对称加密,保证不会在传输过程被第三方篡改。但这里技术上没法保证用户一定使用正确的加密方式,苹果无法知道有多少接入 JSPatch 的用户没有正确加密和校验,这是未知的安全隐患。

第三点在当时并没有什么第三方 SDK 接入 JSPatch,但现在像高德地图/个推等都接入了,如果他们要作恶,或者他们本身服务端被入侵,确实是个安全隐患。

iOS 平台是最安全的,也是最注重安全的,即使热修复带来了 App 质量更高的好处,也无法无视这里的安全隐患,现在 JSPatch 国内覆盖面很大,若出一个安全问题,会影响 iPhone 的声誉,因为这个风险,所以考虑禁掉。

反应

这个警告出来后,国内开发者有各种反应,各种表情贴图还挺搞笑的,不过大家放心,JS没事,iOS 开发该失业的还是失业:)

看到有一些人拍手称赞,赞的理由不是说苹果维护了平台安全,而是:1.国内开发方式low,2.产品经理滥用。这里我有一些想法说一下。

开发方式

他们说国外开发不理解国内为什么要用热修复,国外很少使用,国外开发流程很好很规范,会做好充分的 codereview 和测试,上线后没什么 bug,不需要热修复,也不会有产品经理乱提需求,迭代没像国内这么快,使用热修复是本末倒置,不去考虑提高 APP 质量,国内开发方式太 low,国外的才是正道。

这里有个问题,就是什么是好的开发方式?以什么标准界定?上面的说法可以看出他们是把工程的严谨性,流程的规范性作为好坏的依据。虽然我是个程序员,觉得工程严谨和流程规范确实是好东西,但我比较实用主义,更倾向于以结果作为标准,也就是能不能更低成本更高效地开发出质量更好的产品作为标准。

如果我使用热修复能以更低的人力成本(工程师能力和薪水不如国外,人数少),更高效(测试时间缩短,不需要覆盖到0.01%几率出现的 bug / crash ),做出质量更高的产品( bug / 特殊情况和需求反应速度快),为什么不是一个更好的开发方式呢?

另外客户端的开发方式本身就是落后的,不利于快速迭代,无法对线上产品有控制权,参考另一篇文章。这也就是为什么 Facebook 一开始要用 web hybird 的方式开发,现在又要做 React Native。热修复是这种落后开发方式的弥补。另外我没在国外公司工作过,但感觉他们对bug的容忍程度还是比国内高的,对比一下 IAP 和微信支付的失败率,做过的人都知道。

还有一个声音说国内的人喜欢违反规则,钻空子太不老实。首先前面也说了热修复的方式并没有违反规则,完全符合开发者条例,其次国外也有热修复 rollout,最后如果从开发者条例来说,React Native 反而是违反规则的,因为主要用途动态添加和修改 APP 的功能。

滥用

另一个说法是上了热修复后产品经理来劲了,产品时不时想到一个功能配置说上就上,开发者弱势只能跟着上。

这种情况在我这边团队还没遇到过,我的想法是:如果要上的功能配置对产品是有好处有必要的,开发维护成本又低,为什么不上?如果要上的功能配置是无关紧要的,或者开发维护成本太高,为什么不能讲理拒绝?

开发者把原因定位为自己“弱势”,就把自己从团队剥离开了,变成对人不对事,这种团队氛围是挺糟糕的,而这个锅也不是产品经理的。大家做的事都是为了产品更好,应该不会有那么多故意刁难不讲理的产品经理和老板。至于怎样界定对产品有没有好处和有没有必要,以及开发成本高低,这得自己协商了,以我们团队的做法是以做这个事的性价比计算。

怎么办

接下来如果还想用 JSPatch 怎么办?我没有跟苹果审核团队交流过,不知道他们的想法,短时间内是先不要用,后续再看情况。

热修复的需求很大,很希望苹果可以推出自己的方案,由系统做这个事是可以保证安全的,但现在看起来可能性较低,国外需求量不大,苹果也就不会重视这个需求,何况目前在大力推 Swift。

对于 JSPatch,苹果应该是扫描可执行文件里的关键字,从技术上说是很难禁掉的,可以做各种混淆去绕过检查,但若下发时被查到,会有政策风险,政策有待观察。

实际上动态化还是处于灰色地带,严格来说 RN 是不符合规则的,但还是被允许,只要不给苹果添麻烦,苹果就不会管,JSPatch 因为上面提到的两点风险被管了,怎样做到使用并不给苹果添麻烦呢?

  1. 减少自行接入的使用人数。
  2. 禁止 SDK 接入。
  3. 接入保证传输安全和只用于修复 bug。

第一点警告邮件和代码检查使得自行接入 JSPatch 门槛变高了,显然会减少使用人数。第二点第三点只要有一个平台来管控,由平台保证安全性以及扫描下发的脚本,禁止私有API调用,禁止大量脚本下发,是可以做到的,可能的话希望能跟苹果审核团队协商。

附上 JSPatch 平台初定的解决方案

iOS 开发技术栈与进阶

2017-2-28 评论(17) 分类:技术文章

最近有一些开发朋友问我应该怎样提升自己的能力,回想起来做了这么久 iOS 开发,我也有过那种“让我做一个功能实现个需求我会做,但接下来怎样提高我不知道。”的时期,这里尝试列一下 iOS 开发的相关技术,再说说在学习进阶上我的一些想法。

iOS 技术栈

这里按我的理解给 iOS 相关技术分个类,以工程实现的角度,分成了基础、需求、效率、质量四个类别。基础指程序开发和 iOS 开发的基础知识和技能,需求就是产品的需求,有了基础技能,实现了产品需求后,剩下的事情就都是为了提高项目质量和提升开发效率。

大致的思维导图

iOS技术栈 (更多…)

如何动态创建 block – JPBlock 扩展原理详解

2017-1-23 评论(12) 分类:技术文章

简介

JSPatch 最近新增了扩展 JPBlock,解决之前 block 使用上的一些限制:

  1. block 参数个数最多支持6个。
  2. block 参数类型不能是 double / struct / union 类型。
  3. 不支持 JS 封装的 block 传到 OC 再传回 JS 去调用。

接入 JPBlock 后,就可以:

  1. block 参数支持任意多个。
  2. block 参数类型可以是除 struct / union 以外的任意类型,包括 double。
  3. 支持 JS 封装的 block 传到 OC 再传回 JS 去调用。

这篇文章说说这里的实现原理。

(更多…)

2016

2016-12-31 评论(12) 分类:生活

,照例回顾一下这一年。

工作

微信读书

今年在公司一整年都在做微信读书,用户量一直在增长,UGC方面每天都在产生很多不错的书籍想法和书评,整个产品度过了生死期,进入发展期。产品上有不少地方做得不错,一是保持了简洁的调调,这也是微信相关产品应有的模样,不会有什么乱七八糟的东西,也是很多人喜欢这个APP的原因。二是开放了陌生人想法,一开始微信读书只能看到好友写的想法和书评,跟朋友圈一样保持私密,事实证明在读书这个产品上,开放所有内容才是正道。三是做的阅读时长换书币和赠一得一都取得不错的效果,时长换书币让读书形成正循环。四是做了一些不错的小功能,获得了一些好的口碑,像划线想法制作图片分享,购买/赠送书籍的扉页等。

产品上一直在做一些尝试,但都比较谨慎,很多新需求功能都会经过不断讨论去决定要不要做,也有不少本来已经讨论完觉得可以做,但做到一半或做完时觉得还是不行直接砍掉的需求,谨慎导致不够快速,也做了不少无用功,这里也是我们缺乏经验导致,接下来一年会在这方面寻找解决方法,希望能做到快速迭代,减少无用功。

技术上回顾起来还是做了不少事情的,团队开了个技术博客,今年写了15篇技术文章,几乎每个成员都有贡献,开源了5个库(MLeaksFinder/GYHttpMock/GYBootingProtection/GYDataCenter/GYMonitor),在 APP 质量保证和监控方面做了一些事情,在团队博客上都分享了,另外实施了 code review,团队偶尔也会在项目里做一些新尝试,像尝试使用 RAC,尝试用数据不可变的方式开发,尝试用推荐算法去优化书籍的添加率等等,总的来说还算不错吧。接下来在技术上除了继续保证 APP 质量和开发效率,还应该尝试寻找能帮助产品前进的点。

JSPatch

JSPatch 这一年继续在完善,致力于让 JSPatch 变得更好用,优化了性能,做了一些扩展,填了一些坑,支持了动态调用C函数,做了代码自动补全工具 JSPatchX 等,改进最多的是 JSPatch 平台,从内测到开放注册,添加了灰度下发、条件下发、自定义密钥、在线参数、实时监控、历史补丁、在线编辑、转换器等等功能,已经是一个完善可靠的补丁分发系统,这个以前没有人做过,可以说开拓了在线补丁分发平台这个领域,算是今年主要的作品了,接下来也会继续探索提供更多的服务。

JSPatch 发展到现在已经被很广泛地使用,没有具体统计过接入的 APP 数,仅接入 JSPatch 平台每天有补丁请求的 APP 就有近3000个,在 iOS hotfix 市场占有率应该在 95% 以上,github star 也达到了 8300+,还算不错。

对于 JSPatch 的发展一直想扩展到覆盖 iOS 动态化的全部需求,包括开发功能,上半年也针对这个目标做了些事情,做了性能上的改进,优化开发体验的 JSPatchX 和 playground 等,有一些效果,但开发体验上还是不够好,下半年考虑过做一个100%准确的转换器,实现直接用原生OC开发,动态下发,进一步提升开发体验,但下半年杂事缠身,没能实施,最近看到滴滴和手Q分别实现了这样的方案,也就没打算再做了,后续再看情况。
(更多…)

iOS 动态化的故事

2016-12-21 评论(10) 分类:技术文章

今天聊聊 iOS 动态化的故事。

问题

在开发模式上,web 的方式是比较先进的,有各种优点,包括跨平台/UI开发效率高,最重要的是可以时刻保证用户看到的程序是最新的,没有版本概念,整个系统时刻保持在掌握之中,而客户端开发模式相对 web 开发是一种倒退,客户端做不到这样的动态化,无法随时更新,目前一个客户端程序要更新成本是很高的,需要发布版本,也无法保证所有人都能更新到这个版本,这是最大的弱点,也是非常大的一块需求。

原因

为什么会有这种倒退,最主要原因是:苹果引领的体验优先规则。

在 iPhone 出现之前大家并不太在意一个软件的动画体验,一个 web 应用是很少有动画的,点一个按钮,一整块内容直接刷新,再点个链接整个页面变白刷新,PC上网页滚动都是一格格滚动的,而不是现在手机上那种顺滑流畅的滚动,PC客户端软件也一样,大家都觉得没什么问题,用得挺好,但苹果改变了这种情况,iPhone 刚推出时页面间切换的动画,60fps 的丝滑滚动,点击的即时响应,微软的人都惊呼是黑魔法,让人用了就上瘾,再也回不去,而 web 的方式还不足以像原生客户端那样支持这样的流畅性,做不到好的体验,无法被人接受,开发上优势再多也无法干过客户端,参考 facebook 初期用 web 技术构建 app 的惨状,没办法,服了苹果,大家只能按照苹果的方式干,做原生客户端。

当然这里还有手机环境网络不稳定,流量费贵的原因,但这些都可以在技术上通过缓存解决,最主要还是体验问题。

那发展到今天,这个体验问题解决了没有呢?没有,即使发展到今天手机性能已上天,但 web 做出来的东西体验仍然跟客户端有差别,大家也已经习惯了 APP 的方式,也被流畅的 APP 惯坏。现在 APP 里也有不少功能是 web实现,但大家都知道这是牺牲了一些性能体验去换取开发和发布效率,只是一种权衡。

解决方案

那这个问题怎么解决呢,现在业界有两种方案。

1.优化 web 性能

既然用 web 方式开发的劣势只是性能体验跟不上,那就优化性能吧。web 性能瓶颈在哪里?在那个有悠久历史的 webkit 引擎,它有各种历史问题,要改进它并不容易。我们要的是 web 的开发和发布方式,不需要 web 的全部,那能不能重新实现一个渲染引擎呢,这个引擎可以针对原生客户端优化,不需要兼容繁杂的 web 标准,不跟 web 那些历史问题扯上关系,于是就有了 React NativeWeex 这种方案,web 的方式开发,原生的方式渲染,拥有 web 优秀的开发和发布方式,又有不错的性能体验,看起来很完美,很有前途的方案。

一个方案能不能推广开让大家都使用,主要看成本和收益。目前 React Native 和 Weex 等这些方案的接入成本是很高的,一是它们本身就是大型框架,学习成本高,后期维护成本以及团队学习成本同样高。二是它们还不够成熟,还在继续填坑中,使用的过程可能要一起去填坑。收益上也不够理想,就目前状况它们能代替的是那些本来用 H5 实现的模块,换成这种方式实现后性能体验会更好,但也不能保证像原生那样好,很多场景需要深入框架进行优化。整个 APP 都使用这种方案构建还不靠谱,部分使用又无法使整个 APP 保持动态化,总体上来说收益也没有达到有绝对优势的程度,成本高收益低,推广起来会比较困难,还需期待其继续发展。

2.原生动态化

另一种是方案是,我可以放弃用 web 的开发方式,放弃 web 跨平台/UI开发简单的优越性,我想继续用原生的方式开发这个APP,但又希望这个 APP 随时可以更新,让程序时刻在自己掌握中,出了问题可以快速修复,还想要可以随时更新版本快速迭代,可以不?完全可以,用动态库就行了。

动态库

技术上要在 iOS 上做到原生动态化比 Android 更容易,iOS 开发语言 Objective-C 天生动态,运行时都能随意替换方法,运行时加载动态库又是项很老的技术,只要我把增量的代码和资源打包到一个 framework 里,动态下发运行时加载,修 bug,加功能都不在话下,性能完全无损,这件事就结束了。

但是呢。苹果把加载动态库的功能给封了,动态库必须跟随安装包一起签名才能被加载,无法通过别的途径签名后再下发。

为什么这么做呢,这又涉及到苹果另一个创举:审核模式(苹果的创举之多令人发指)。一个软件,要在一个平台上发布,需要先通过这个平台的人工审核,这个好像在苹果之前没见过有别人这样做过,windows 不用,mac 不用,各种 unix 不用,web 也不用,苹果为了对自己的平台有绝对控制权,搞了这样一个东西,审核模式就跟动态化冲突了,如果我一个 APP 可以不经过审核不断下发 framework 添加修改功能, 还需要苹果审核做什么?

因为这种限制,没法用最方便的方式进行动态更新了,整个 APP 发出去后就不受控制,有什么严重 bug,需要添加什么功能,都乖乖打个包提交给苹果审核,再等用户慢慢更新,对于急性子的中国人来说,这种事难以容忍。

绕道

苹果把动态库这扇门关了,我们可以绕个道从另一个门进,动态加功能可以缓缓,大家需求还不那么迫切,但修 bug 的需求就很急,很多公司 APP 的 crash 率是 KPI 来着,看着线上 crash 不断增多又毫无办法是很不爽的事,于是有了 waxPatchJSPatch 这种方案,曲线救国。

JSPatch 把 OC 手动翻译成 JS,在运行时通过 OC 的动态特性去调用和替换 OC 方法,实时修复 bug。修 bug 这个需求基本是满足了,虽然小绕了下道,但成本还是很低的,引擎本身也很小很轻量,接入对 APP 不会有任何负面影响,在关键时刻又可以帮大忙,成本低收益高,于是很容易推广开。

人欲望是无穷的,技术宅的折腾是无止境的,JSPatch 满足了修 bug 的需求,但还是无法满足动态化的全部需求,最大的缺点在于需要手写 JS,虽然已经有转换器辅助,但还没做到100%准确,用来修 bug 还好,用来添加功能的话学习成本和开发效率还不够。

于是有了滴滴的 DynamicCocoa 这种方案,绕了一个更大的道,从编译阶段入手,通过 clang 把 OC 代码编译成自己定制的 JS 格式,再动态下发去执行,做到原生开发,动态运行,主打动态添加功能,当然顺便把修 bug 也给支持了。手机 QQ 内部也有一个类似的方案,不过更进一步,他们通过 clang 把 OC 代码编译成自己定制的字节码动态下发,然后开发一个虚拟机去执行(惊呆了),同样实现了原生开发,动态运行,都是 NB 得很的方案。只要底层处理做得足够好,也是个成本低收益高的方案,不过目前都还没开源,还没能看到实际效果和 NB 的源码,挺期待。

审核

这种方案有没有什么问题呢,问题在对于苹果审核比较尴尬。这种方案做到极致后(所有OC/C语法都支持),实际上是绕道实现了动态加载 framework 的全部功能,开发体验还是一致的,如果苹果同意这种方案,那相当于允许加载动态库,那还不如直接把门开了,让大家直接用动态库去做这个事情,用动态库还能在签名时禁止使用私有 API,用这种编译成脚本/字节码下发的方案可就禁止不了了。

这跟 JSPatch 还不太一样,JSPatch 虽然我也想推广动态添加功能的用法,但因为开发体验问题大部分还是用于修 bug,苹果审核对 JSPatch 开始也是有一些拒绝案例,后来估计看到大家只是用它来修 bug 和 crash,提升 APP 的质量,就默许了。但 DynamicCocoa 和手Q的方案一开始目标和效果就是跟加载动态库对齐,大规模推广后苹果会怎么看就不知道了。

我觉得苹果现在的审核方式挺有问题的,有多少APP是审核时用一套,审核通过后又通过后台一些开关把不符合规则的一些功能开放出来?只要能连上网,就有N种方式修改 APP 里的功能,苹果完全拦不住。个人认为审核方式应该改为只在发布新 APP 时审核,发布后允许动态下发代码更新,版本更新也不需要重新审核,而是通过举报和抽查的方式去审核已上线的 APP,这样既能顾及开发效率,方便开发者快速迭代做出更好的 APP,也更能确保审核效果,只是实施起来没有现在简单粗暴。

最后

故事讲到这里已经差不多了,再多说一点,有个让我觉得很奇怪的问题,就是国外开发者只热衷于使用第一种方案解决问题,也就是使用web技术,用 React Native / NativeScript 的方式去做这个事情,对第二种方案很冷淡,包括 iOS Android 都是,原生热更新只在国内火,国外根本不感冒,国外有个 rollout 热更新平台也不温不火,为什么呢?是国外用户更守规则,或是用户对线上 bug 容忍度高,开发者对线上 bug 并不那么着急?还是 Android 被 Google Play 卡死断了这念想,iOS JSPatch 之类的方案推广不利?缺少国外一线开发者的支持,让系统原生支持动态化就比较困难了。

个人认为由系统支持动态化(允许加载动态库)在当前环境下是最好的,兼顾开发效率和 APP 体验,虽然不能跨平台,但也还能接受,可惜这个主动权掌握在苹果手上,开发者无能为力,才会出现这么多强行绕道突破的方案。web 的方式可能是未来,但目前适用范围有限,接下来怎么发展,拭目以待吧。

APP 缓存数据线程安全问题探讨

2016-11-22 评论(11) 分类:技术文章

问题

一般一个 iOS APP 做的事就是:请求数据->保存数据->展示数据,一般用 Sqlite 作为持久存储层,保存从网络拉取的数据,下次读取可以直接从 Sqlite DB 读取。我们先忽略从网络请求数据这一环节,假设数据已经保存在 DB 里,那我们要做的事就是,ViewController 从 DB 取数据,再传给 view 渲染:
cache1

这是最简单的情况,随着程序变复杂,多个 ViewController 都要向 DB 取数据,ViewController本身也会因为数据变化重新去 DB 取数据,会有两个问题:

  • 数据每次有变动,ViewController 都要重新去DB读取,做 IO 操作。
  • 多个 ViewController 之间可能会共用数据,例如同一份数据,本来在 Controller1 已经从 DB 取出来了,在 Controller2 要使用得重新去 DB 读取,浪费 IO。

cache2
(更多…)

汽车杂想

2016-10-30 评论(5) 分类:生活

我一直对汽车不怎么感冒,去年五月因为家庭需要买了丰田雷凌,开得比较少,只有周末和有需要的时候才开下,说说对汽车的一些想法和感受。

刹车油门

在自动挡的汽车里没有了离合,只剩下两个踏板:刹车和油门,本来这两个踏板刚好对应两只脚,左脚刹车右脚油门,但现在还是全部由右脚控制,左脚空闲着,这样有两个优点:

  1. 避免刹车和油门同时踩。若两只脚对应两个踏板,慌乱的时候可能会两个踏板同时踩,不过这点很容易从技术上弥补,踩刹车的时候让油门失效就行了。
  2. 跟手动挡的车兼容。手动挡左脚是需要踩离合的,右脚就必须兼顾这两个踏板,若自动挡改成两只脚控制,在这两种车间切换的学习成本会变得很高,也会很混乱,估计这是最主要的原因。

同样也有两个缺点:

  1. 右脚会很累。特别是在市区拥堵路段,右脚需要不断在刹车和油门之间变换。
  2. 从油门到刹车切换需要时间。这时间可能已经够快,但在关键时刻还是浪费了些宝贵的刹车时间。

总的来说这种方案是缺点大于优点的,如果世上没有出现过手动挡汽车,可能还是会设计成左脚踩刹车,右脚踩油门。

还有一个小细节,现在由一只脚控制刹车和油门,那就需要尽力避免右脚混淆这两者,避免把刹车当油门,把油门当刹车的情况。就我的车雷凌来说,做了两点去保证这个区别,一是刹车面积比油门大,误触刹车比误触油门安全得多。二是刹车和油门这两个踏板不在一个平面上,刹车会稍微高点,稍微往前点,让脚放在刹车上跟放在油门上是两种不同的感觉,让脚抬起的度数去感觉现在是踩在刹车上还是油门上,这种身体的记忆是最可靠的,同时刹车高点也会比油门更容易踩。不知是不是所有车都这样。

空调

开车到现在碰到最大的痛点就是空调问题了,夏天只要放在路边,没多久车内温度就会非常高,没法待,这时候通常都是先进去发动汽车开空调,再在车外等车内温度稍微降低后再进去,等待的时间也很长,非常麻烦。怎样解决这个问题呢?

第一个能想到的是加强空调的强度,让汽车快速降温,不知道技术上能不能做到。我对汽车本身不太感冒,宣传的那些参数都看不懂,我觉得应该在那些参数里加一项,可以在多少秒内把车内温度从50读降到25度,这点应该很有参考价值。

第二是支持远程开启汽车空调,一查发现原来已经有不少汽车支持这个功能了,有的是远程开启发动机后供电开启空调,有的是用车内蓄电池供电开启,但远程开启发动机有点危险的感觉,车内普通的蓄电池电力又不足,这个功能应该更适合那种混动或电动汽车。

屏幕

车上装了个屏幕,是上个时代的产物,虽然有很多功能,什么电台/导航/音视频什么的,但很不好用,屏幕质量也差,非常鸡肋,唯一的作用是倒车时显示后视摄像头,平时其他功能都是直接使用手机,然后我还得买个手机支架挡在汽车空调风口去使用手机。

这里的问题是汽车换新的速度比手机差远了,一般人八年十年才会换一辆车,但一两年就会换一次手机,导致手机屏幕和功能一定秒杀汽车屏幕。另外像特斯拉那种放一个巨大触摸屏在汽车也不是好的方案,调个空调什么的都要通过屏幕,没法通过位置和触感盲按,在驾驶过程中调节麻烦又危险,大屏幕在汽车上并没有什么大用处,而且这块固定的屏幕也很快会过时。手机在未来很长一段时间应该还会继续在屏幕方面处于统治地位,新型汽车应该把本来留给屏幕的位置换成留给手机,做好手机和汽车的连接体验才是正道。

自动驾驶

自动驾驶目前在 AI 领域很火热,它带来的好处自然是很吸引人,驾驶的事交给机器,自己在车上就可以看看电影玩玩游戏,取车停车都能交给机器做,相当于每个人都有专属司机,目前号称自动驾驶出事故的概率比人低得多,机器比人更可靠,自动驾驶大规模使用指日可待,但这里感觉有个很大的隐患,就是程序病毒。从概率上说虽然人可靠程度不如机器,但人可不会突然中个病毒,然后在开车的时候乱来,但机器会,无法预测程序中病毒以后的行为,也无法事先感知程序中了病毒,现在在起步阶段,自然不会有这样的问题,等到真正大规模使用了,受到黑客的关注多了,自然攻击会变多,这里有很大的不确定性,把自己的生命交给这样的不确定性恐怕大家难以接受,估计也只敢在停车和取车时空车模式使用。

其他

私家车相对于打车和公共交通有好处也有坏处,好处是干净舒适,无需等待,无需步行到车站,也不用担心没有车,心情好的时候驾驶的感觉很不错。坏处也不少,开车时除了听歌听电台无法做其他事,相对地铁有塞车的烦恼,停车是个巨大的麻烦。另外成本也很高,得交停车费,得保养车,路上擦碰要修理,一不小心还得违个章。这样算起来,在公共交通和优步滴滴这样的出行方案成熟的情况下,开私家车真是挺奢侈的。