转自:http://www.jiajun.org/2011/06/18/use_three20.html


记:Three20(简称:TT)是Facebook维护的一个开源iPhone应用框架。框架封装了一系列视觉控件,网络组件,和工具方法。最近使用TT重构了一个app,这个app在1万行规模使用的是原生代码,架构非常简单。增长到2万行规模,这个原生的架构已经疲于应付迅速变化的业务需求,因此我们采用TT进行了重构。这里,简单介绍一下使用TT开发的app采用了怎样的架构,以及开发过程中的经验和教训。

app基于TTTableViewController的架构进行设计,主要分为三层:ViewControlelr,DataSource和Model。另外,平行于这三层设有Service和Util,封装一些通用逻辑和工具,例如:登陆,URLEncode等。最底层是Manager,封装网络控件,缓存控制等。除了这些还有独立封装的组件和对系统组件的扩展,如SegmentedControll,滚动图片等。这个架构不做赘述,说一说在这个架构下遇到的几个问题,以及解决方案。

1、TT对系统控件的封装无法满足个性化需求。

TT对很多系统控件进行封装,拿之前提到过的TTTableViewController举例,所有的cell都被封装,对框架使用者透明,而TT封装的cell类型无法完全满足需求,我们往往需要格式更加丰富的cell样式。

在这种情况下,我们选择对TT方法进行重写。Objective-c提供指定类指定方法的重写,因此集中把需要个性定制的TT控件进行重写,完全不修改TT本身的代码。这样操作,既满足了需求,又使在日后对TT框架进行升级变的非常方便,几乎不需要考虑升级造成的不兼容。

2、Cell的默认操作过分单一

TT是使用Navigator和ULR的策略(欲了解该策略请参考TT官方网站http://three20.info)来管理整个应用的ViewController的。

在TableView中没一个cell带有URL,这个URL表明了点击cell后要跳转到的viewController,同时TT还认为如果一个cell没有URL那么他就是不可点击的,而往往存在这样的需求,cell可点击,但点击操作却不是跳转到某个ViewController。

针对这种情况,我们定义空URL,空URL不指向任意ViewController的类,而是指向nil。带有空URL的cell既可点击,又不会跳转到任意ViewController。

3、构造ViewController的URL不支持中文

之前说了,TT使用URL管理ViewController。有些ViewController的参数是中文,而且需要通过URL传递,而Navigator不支持汉字URL。

增加URLEncode方法,对每一个配置到URL中的参数编码,生成编码后的URL就可以正常使用。另外,TT会自动Decode的URL,无需开发者处理。

但TT的在URL策略中“/”无法使用,即使进行Encode之后,放入URL仍无法使用。这就需要开发者在构造URL过程中,检查每一个参数,确保不出现“/”。

4、稳定版TT(v1.0.5)不支持ios3.1及以下版

根据我们对客户端使用ios版本的统计,3.1及以下版的用户仍然占一定比例,还不能放弃支持。因此,考虑到支持3.1及以下版本的ios设备,需要使用v1.1 TT进行开发。

开发过程中遇到的问题很多,以上是比较明显的几个,接下来聊一聊开发经验。

1、一个界面一个ViewController

在一个应用中,ViewController往往通过简单的配置就可以复用,可以控制多个界面,但我建议ViewController不复用。复用ViewController必然导致在类中出现用于区分不同界面的逻辑,如果界面上的逻辑稍有变动,这个被复用的Controller要跟着修改,随着发展,代码会越来越复杂,因此,保证一个界面一个ViewController。

对于那些确实可以复用的逻辑,可以采用继承的方式。把可以的复用逻辑封装在一个类中,每一个直接控制界面的ViewController继承自这个父类,针对各自的个性逻辑重写相应的方法。

2、不过分使用URL

之前我们提到多次通过URL控制ViewController,Controller中的参数也可以通过URL传进去,但过度使用URL构造Controller可能会埋下隐患。URL不仅是初始化的时候使用,在运行过程中可能还需要使用这个URL在池中取出该对象。如果在URL中定义了多个参数,在获取对象的过程中,必须拿到这些参数值才能准确定位到相应对象,往往这些参数都不是全局的,所以这个过程就会非常麻烦。

因此,在某些非终端的类中,尽量不使用URL构造对象,需要传递的参数使用ApplyQuery的方式,使用一个字典构造Query,使用URLAction构造对象。

3、封装两个网络控件,带缓存/不带缓存。

TT封装的网络控件叫TTURLRequest,在TTURLRequest中允许使用缓存,默认缓存1天。在应用中,有些请求要求实时性,不允许使用缓存,尤其是一些写操作的请求。

应用本身也要对TTURLRequest进行一层封装,就是之前提到过的Manager,在NetworkManager中封装两个方法,使用缓存/不缓存。

4、使用延迟加载操作

所谓延迟操作,指的是在某个界面上加载某个组件的时候,如果直接调用addSubview方法可能会出现加载失败等诡异问题。是由于iPhone渲染一个界面需要时间,加载自己的组件需要在渲染界面之后,而调用viewLoad,甚至是viewDidLoad方法在TT框架下不能保证在渲染完成之后。因此在加载个人组件时,可能需要延迟加载,即,延迟0.3或0.5秒后再加载。TT框架本身也采用了许多延迟加载,使用[NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval) invocation:<#(NSInvocation *)#> repeats:<#(BOOL)#>]方法。

以上介绍了8个经验和教训,希望能对大家在使用TT进行开发过程中提供一些帮助,少走弯路。


Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐