购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

Tip 12

命名空间

Objective-C一直以来令人诟病的一个地方就是没有命名空间,在应用开发时,所有的代码和引用的静态库最终都会被编译到同一个域和二进制中。这样的后果是一旦我们有重复的类名的话,就会导致编译时的冲突和失败。为了避免这种事情的发生,Objective-C的类型一般都会加上两到三个字母的前缀,比如Apple保留的NS和UI前缀,各个系统框架的前缀SK(StoreKit),CG(CoreGraphic)等。Objective-C社区的大部分开发者也遵守了这个约定,一般会将自己名字的缩写作为前缀,把类库命名为AFNetworking或者MBProgressHUD这样。这种做法可以解决部分问题,至少我们在直接引用不同人的库时冲突的概率大大降低了,但是加前缀并不意味着不会冲突,我们还是会遇到即使使用前缀也仍然产生冲突的情况。另外一种情况是,你想使用的两个不同的库,引用了同一个很流行的第三方库,而又没有为其更改名字,当你分别使用这两个库中的一个时是没有问题的,但是一旦你将这两个库同时加到你的项目中的话,这个大家共用的第三方库就会和自己发生冲突了。

在Swift中,由于可以使用命名空间,即使是名字相同的类型,只要是来自不同的命名空间,都是可以“和平共处”的。和C#这样的显式在文件中指定命名空间的做法不同,Swift的命名空间是基于module而不是在代码中显式地指明,每个module代表了Swift中的一个命名空间。也就是说,同一个target里的类型名称还是不能相同的。在我们进行app开发时,默认添加到app的主target的内容都是处于同一个命名空间中的,我们可以通过创建Cocoa(Touch)Framework的target的方法来新建一个module,这样我们就可以在两个不同的target中添加同样名字的类型了:

在使用时,在可能出现冲突的时候,我们需要在类型名称前面加上module的名字(也就是target的名字):

因为是在app的target中调用的,所以第一个MyClass会直接使用app中的版本,第二个调用我们指定了MyFramework中的版本。

另一种策略是使用类型嵌套的方法来指定访问的范围。常见的做法是将名字重复的类型定义到不同的struct中,以此避免冲突。这样在不使用多个module的情况下也能取得隔离同样名字的类型的效果:

使用时:

其实不管哪种方式都和传统意义上的命名空间有所不同,把它叫作命名空间,更多的是一种概念上的宣传。不过在实际使用中遵守这套规则的话,能避免很多不必要的麻烦,至少我们不需要再给类名加上各种奇怪的前缀了。 48Hd1ecK0pCXnGNHG0s0M5baCrtiwCuDhoJXQIZhz6L6C3BWbCTxNaLb5NDUFRLN

点击中间区域
呼出菜单
上一章
目录
下一章
×