Category 还可以有什么用途?

除了帮原有的class 增加新method,我们也会在几种状况下使用category。

将一个很大的Class 切成几个部分

由于我们可以在建立class 之后,继续透过category 增加method,所以,假如一个class 很大,里头有数十个method,实现的代码上千行,我们就可以考虑将这个class 的method 拆分成若干个category ,让整个class 的实作分开在不同的档案中,方便知道某一群的method属于什么用途,也方便日后维护。

切开一个很大的class 可以收到的好处包括:

跨Project

如果你手上同时有好几个Project,我们在进行Project的时候,由于之前写的程式码可以重复使用,造成每个Project可能共用同一个class,但是每个Project又不见得都会用到这个class里头全部的实现,我们就可以考虑将只属于某个专案的实现,拆分到一个category 中。

跨平台

做为写Objective-C语言的工程师,我们非常有可能会遇到跨平台开发的需求,如果我们某段代码只有用到Mac OS X与iOS都有的library与framework的话,我们的程式就可以同时在Mac OS X与iOS使用。当我们打算在Mac OS X与iOS共用同一个class,我们就可以考虑将跨平台的部份与平台相依的部份拆开,将只属于某个平台的部份拆成另外一个category,以苹果自己的例子来说,在Mac OS X与iOS上都有NSString,但由于两个平台在绘图方面的实现有所不同,所以在绘制字串的部份,就被拆分到NSStringDrawingUIStringDrawing这些category中。

替换原本的实现

由于一个class 有哪些method,是在runtime 时加入的,所以除了可以加入新的method 之外,假如我们尝试再加入一个selector 与已经存在的method 名称相同的实现,我们可以把已经存在的method的实现,换成我们要加入的实现。这么做在Objective-C语言中是完全合法的,如果category 里头出现了名称相同的method,compiler还是容许编译成功,只会跳出简单的警告讯息。

实际上,这么做却非常危险,假如我们自己写了一个class,我们又另外写了一个category 置换其中的method,当我们日后想要修改这个method 的内容,很容易忽略在category中的同名method ,结果就是不管我们怎么改动原本method里头的代码,结果却是什么改变都没有。

我自己曾经犯过一个低级错误:在开发时我建立了另外一个git分支,在新分支中,我觉得某个class 太大,于是将部分method拆到了另外一个category 中,但是开发主线却又在修改这个class,结果造成合并分支的时候,就变成原本的class 与category 中出现了相同的method,花了半天的时间才找到问题出在哪里。

除了某一个category 中可以出现与原本class 中名称相同的method,我们甚至可以在好几个category 中,都出现名称相同的method,哪一个category 在执行时被最后载入,就会变成是这个category中的实现。那么,如果有多个category,我们怎么知道哪一个category会被最后载入呢?Objective-C runtime 并不保证category 的载入顺序,所以我们必须严格避免写出这种程式。

results matching ""

    No results matching ""