这几个月中做的工作包括网站开发、安卓App开发和苹果App开发,前两者用的语言都是我熟悉的java,故苹果知识的学习,较安卓知识的学习,多出「语言基础」一块,其他方面差不多。
之前发过安卓那篇,如感兴趣,戳我的名字看吧。
0.语言基础
去年购入mac开始学ios编程时用的是swift,今年用的是objective-c(下简称oc)。
网上有将oc与java对比的博文,其实面向对象各种语言,能力大同小异,主要是写法不同。oc最大的特殊,当为用中括号调用方法,我感觉这很丑陋怪异,但想到目的是让每个参数的意义在代码中都直接呈现,除了用中括号也没别的好办法。
属性却支持用点符号调用,看似直接向字段写、赋值,实际调用的是getter/setter方法,就像jsp里写el表达式时某某点某某,实际调用的是getter。
以前看c代码,最奇怪的是h文件和m文件的关系,以及引用的方式,不像java那样一个public class声明,互相import即可,认为深奥玄妙,深不可识。其实只是固定写法,h声明一些公有方法,m实现这些方法,并可以同时声明一些私有方法,有点像java的接口声明和实现类(xxImpl),但oc对应「接口」的概念是「协议」,用prototype声明,确实,用「协议」更形象,它本来勒定的就是实现者的能力,像java声明接口时常叫「xxAble」一样。
其他基础语法不赘,跟java的功能类似,只是换了个外观,参考《objective-c编程》《objective-c高级编程》《Effective objective-c》三本书就很好。比较引人注目的,是《objective-c高级编程》的三大主题,即「自动引用计数」「Blocks」和「GCD」这三大语法糖,大概对应java的内存回收中的引用计数知识、java使用匿名内部类实现回调函数、java尤其是android编写跨线程的代码这三个主题,在后两个方面,古老的java写法确实略显笨拙,oc的语法糖很方便。不过我比较土,java8至今尚未研究过,不清楚其语法糖方便程度如何。(有空要研究下java8、scala、groovy这些据说方便的概念)
1.开发环境和参考资料
参考资料方面,由于学会FQ时间较短,大部分时间用的主力参考书是手边几本纸书,某两本翻译的外国书被我塞到床底下决定不看了,非常不满意,《iOS开发指南》和《iOS9开发指南》这两本人民邮电出版社的国产书我很喜欢。引进的翻译书,有些作者「自我意识」过重,不肯按知识体系,分层次地安排章节,而是按着自己一厢情愿的「意识流」安排,强迫读者跟着他的想法走,而他安排的顺序,又不把体系结构、基础知识、最核心常用技能放在重要位置,而是「反正我的书我说了算」,把些很边缘的知识,在其基础知识尚未交待的情况下就仓促提出,缺少基础知识根本看不懂,即使费力看懂了也没太大用。我总在想,也许确实国人骨子里懂老子「后其身而身先」的教诲,更懂得把自己摆在一个次要的位置,以阅读者的大脑为目标,把知识好好梳理安排,尽量舒服地送进读者的大脑去,这样「满足了需求」,读者喜欢,销量自然好,「名」和「利」自然随之而来。而不是存在感极强地勒令读者跟着他走。不过话不能说绝,《iOS8应用开发入门经典》就相当不错,以及我读过的很多很多外国书籍都很好(早些时候写的个人书单),上面仅限于对一些「定位于入门书却对小白很不友好」的书的不满。
话说多了,接着说书,上述四本书都是去年买的,《Swifter》《iOS开发进阶》和《objective-c编程》也是。最后一本语法书,很有细细阅读的必要,重要的点基本都讲到了,但没写过代码时看一些知识可能会难理解,边写代码边常读它就不错,《objective-c高级编程》和《Effective objective-c》是前天才买的,薄得让人惊讶,但内容都不错,前者讲「三大语法糖」,不多说,后者只要读过《Effective Java》或《Effective Javascript》自然会天生带有好感(C++那本我没读过,估计也极好,这就是「品牌效应」),翻开看看,果然都是些最佳实践的建议,像《圣经》中的箴言,轻轻读一则,就能有所获,熟悉的味道。另外,前天还买了本《iOS Auto Layout开发秘籍》,之前在storyboard中布局时,对控件的约束让我伤透了脑筋,不知道该参考什么资料,只好摸索着弄,有了这本书,可以强化一下。
上面说的是书,后来看了看官网文档,感觉非常好,虽然我英文阅读能力不是很强,但配合着有道词典的取词插件阅读起来阅读效果还可以。官网的优点是权威,新,简洁精准,安排合理,这是比所有书籍都好的方面,以至于很多人说有了官网文档就不必买书了,不无道理。但官网文档这样多,用哪个「目录」做全景概览,以什么「次序」做阅读学习呢?「搜索框」急用可以,能头痛医头脚痛医脚(但这方面似乎也不如google + stackoverflow),但作为「系统学习」的起点就太没次序和脉络了;网络上一篇讲阅读次序的帖子,有点过时了,虽然万变不离其宗,但对陌生于文档的新手,当「万变」发生之后,怎样才能「不离其宗」?作者没说。最后发现还是最老实的官网文档入口页http://developer.apple.com/develop/就不错,tutorial做导航图,api做字典,用前者寻找特定技术主题,用后者理解不同类库功能,穿插学习一段时间,就能对重要知识有所掌握了。
除了书和文档外,开源应用也是很好的学习对象,因为它是鲜活的,在模拟器里直接能跑,还能改改代码看效果,下下断点看奥妙。我用的是开源中国的iOS客户端的源码。读源码,我习惯的方法是第一遍先概览、通读,不管三七二十一,读将下去,不用太细,不用开模拟器,按最基本的线性顺序,把整个项目的代码过一遍(当然,有些包里类的技术大同小异,只有业务的区别,则不必全读,读三分之一即可),然后第二遍,开模拟器(如果是web应用就是跑应用开浏览器),关注特定功能的来龙去脉,理解界面展示和响应时自始至终代码的执行流程,对象和对象是怎么组织的,类的父类是怎么封装的,重点看脉络流程,至于具体的第三方或基础类库的使用,方法的调用,细微的算法,如果感觉能学到东西,看看也可以,不看也没关系。重要的是,观察源码中分包分模块的体系结构、功能响应时的流程流转,这是「树干」和主要「分支」,至于具体细微的树枝和叶子,暂时忽略之可也。
开发工具xcode,我到现在对之也不算熟悉,好在写代码的部分,会基本的打字、复制、粘贴就行了,更高深的使用,当觉得「xcode估计有这个功能」时,去google搜一下就行了,xcode的使用,《iOS9开发指南》很简单的介绍很实用,官网更有详细的教程(还没看),《iOS开发进阶》则给出了一些实用的工具(还没用),感觉再加上搜索引擎,就没有问题了。重要还是要熟练,「工欲善其事」嘛。
2.页面知识
页面知识两大要点:一是在单个页面中,组件的使用和约束的使用,二是多个页面的协作。
单个页面中,基本组件加到页面中最简单,拖拽即可,绑定到Controller的变量上、及绑定响应方法也极简单,同时开storyboard和Controller,拖拽即可。因为「Controller持有控件」与「Controller提供响应函数」是有界面编程(且不管命之曰mvc还是mvvm吧)天经地义的规则,所以xcode直接用ide实现了,而不像android那样还要用第三方的ioc框架,或者angular那样手动的声明。当然,如果比较喜欢鼠标的移动和左右键的点击,以及键盘组合键的使用,喜欢「码之」而不是「拽之」的同学,手动写代码声明组件对象,并添加到Controller的属性上,添加到Controller的view中,甚至手动添加约束,也是可以的。只是,这样做,比起拽来拽去,工作量未免多太多了,所以什么时候用码的,什么时候用拽的,就要视组里结构及项目特征而定,对于我个人,因为单打独斗,又是新手,所以两种都试试,在实践中学习之。
组件可以自定义,这是当然的,跟android一样,提供一个回调方法,在其中用画布绘制自己的自定义样式,即可声明一个组件类。不多说。
使用约束,大约对应android的RelativeLayout,相对布局,在网页布局中对应的却不是position:relative而是absolute,脱离文档流。手动指定谁在谁左面,谁在谁上面,距离多少。但这种方法,始终是「奇兵」,「正兵」依然是先上后下、先左后右的线性布局,即html中的文档流,android中的LinearLayout,iOS中怎么实现?看开源中国的代码,开了个眼界,用tableview实现LinearLayout的效果,指定第一行单元格应该是啥,第二行应该是啥..不过感觉,这跟古老的html中用table布局有异曲同工的地方,html的table布局早就被扬弃了,不知道iOS中,tableview当LinearLayout的用法,是不是主流,还是有更好的方案,需要继续研究。
多页面协作,最常用无非是基本弹出、进退导航、标签切换这三种,除了基本弹出太基本外,进退导航和标签切换也被提供了原生的支持。android中标签放到底部,还需要手动实现,iOS直接拖拽就行了;但iOS中Navigation导航还要在storyboard上布置下,android相对简单些,究其原因,是android手机自带后退键,故「前进」「后退」是天经地义,而iOS只能在标题栏显示按钮来点。相比网页,网页中的主要跳转当然是前进后退,进栈出栈,而「选项卡」在网页中多作为局部控件点缀使用,与app的「标签」对应的其实是网页的「菜单」,但网页点击菜单,其实一般也是「前进」的,除了opoa的新潮页面,和古老的iframe嵌套页面外。但app的标签切换基本就相当于iframe.src赋值。
3.数据知识
app的数据知识,无非两点,一是本地存储,二是rest交互。
本地存储,分为直接写文件、写键值对、写数据库三种,都有基本实现,不多说。
rest交互,自带或第三方都有方便的库,根据供求关系,基本需求必有方便供给,也不用多说。
4.实践经验
其实苹果版app到现在也未上线,这方面经验还待补充。
功能实现,基本上界面知识与数据知识结合即等于一切,在前面安卓那篇给过的公式。
第三方依赖,也是有事实标准的,不多说。
登录逻辑,跟安卓逻辑一样,只是不同平台具体代码的区别,不多说。
app嵌html,也没实际用过。
5.个人感想
我不喜欢oc,我讨厌大括号调用的写法,我不觉得把方法每个参数的含义都显示出来有什么必要性。
但不能只用swift,好比java开发虽然ssh是主流,直接用servlet的少见了,但servlet的基础才是安全感和信心的保障和来源。
而且,据说swift也难免要用到oc的遗留类,躲总是躲不掉的。
或许oc变熟悉之后,再看c和c++的代码都会更熟悉一点?
面向对象的语言,封装继承多态,万变不离其宗,拥有界面的编程,状态事件响应,是亘古不变的规矩。mvc和mvvm?区别有想象中那么大么?
越做应用就越觉得荒芜,感觉在同一地方兜兜转转,所谓语言切换,打通全栈,也不过是今天吃个苹果,明天吃个梨子的变换,变来变去都是一样。
就回头,在毕业几年后,回头学计算机组成原理,操作系统,数据结构和算法,网络。之前的几年,我学的是设计模式,重构,软件工程,语言框架。
计算机的海洋,浩瀚无边,编程语言和应用领域,以及具体产品,其实都是客体,内功强大了,用什么招式,拿什么语言,都能虎虎生风。君子不器。
而内功,也许是哲学,理解世界运行的方式,才能在程序里更好地模拟之。(例如:面向对象)
也许是心理学,理解用户生活的习惯,才能在设计上更好地帮助之。
也许是逻辑能力和思辩方式,有了更好的沟通能力,才能跟同事、用户、客户产生高质量的交流,而交流,是产品之本。
也许是FQ能力,英文水平,搜索引擎使用能力,阅读能力,写作能力。
这些都很重要,但我们总是忽略它。
「不用管别的,现在就开工写代码,有了问题『百度』一下!」
多少次就这样,在战术上的勤奋,日复一日的加班中,像拉磨一样原地打转,自以为做了很多工,实际上却无进展。
很多时候该退出来,在战略上想一想,这五年打算做什么,下个五年呢?
我们要养成的,是布局自己人生的习惯。
「与其恋子以求生,不如弃子而取势」,有价值的事情,未必就要做,所谓「价值观」,所谓「取舍」,都包含了舍弃有价值的东西的部分。
而我们最宝贵的,是时间,做了这,就不能做那,在经济学上,这叫「机会成本」。
如果我们希望,在有生之年,在世界上打出一块属于自己的天地,那我们现在该准备的是什么?这才是问题的关键。
不要拉磨拉得兴起,汗流浃背天天加班,每月赚个两三万就心满意足了。这真的是你青春的价值吗?
此时此刻你身边蠢人对你是羡慕嫉妒恨,还是小瞧,真的并不重要,你活着不是为了给他们看的。
这篇写iOS,非常小白,基本没有价值,如果有价值,就是这里议论的几句话。
希望对有缘看到这里的编程的朋友有所启发。
因为我们知道,我们中很多朋友,是会钻到代码浑然忘我的,这很好,能让编码能力猛增,但同时,可能会忘了后退一步看看天空。
别用战术的勤奋掩盖战略的懒惰。
多想一想。
弃小取大。
布局人生。