Objective-C等同于Java的包吗?
Objective-C不像Java和C++那样有包或命名空间的概念。造成这种情况的部分原因是Objective-C最初只是在C语言的基础上添加了一层轻量级的运行时层,并以最小的麻烦将对象添加到C中。不幸的是,使用Objective-C时我们必须处理命名冲突。有得必有失。
需要澄清一点(虽然并不令人欣慰),Objective-C实际上有两个扁平的命名空间——一个用于类,一个用于协议(类似于Java的接口)。这并不能解决任何类命名冲突,但它确实意味着您可以拥有同名的协议和类(例如NSObject和NSObject),其中后者通常采用(“实现”)前者。这个特性可以防止在Java中泛滥的“Foo / FooImpl”模式,但不幸的是对于类冲突没有帮助。
命名:
下面的规则是主观的,但它们是命名Objective-C类的不错准则。
- 如果您的代码不能被其他代码运行(不是框架、插件等,而是最终用户应用程序或工具),您只需要避免与链接的代码冲突。通常情况下,这意味着您可以完全不使用前缀,只要您使用的框架/插件/捆绑包具有适当的命名空间。
- 如果您正在开发“组件化”代码(如框架、插件等),您应该选择一个前缀(希望是独特的),并在某个可见的地方记录您对其的使用,以便其他人知道避免潜在的冲突。例如,CocoaDev维基是一个事实上的公共论坛,用于声明对前缀的所有权。然而,如果您的代码是类似公司内部的框架,您可以使用其他人已经使用的前缀,只要您不使用具有该前缀的任何内容。
组织:
不幸的是,许多Cocoa开发人员对将源文件组织在磁盘上并不够重视。当您在Xcode中创建新文件时,默认位置是项目目录,就在项目文件旁边等。个人而言,我将应用程序源代码放在source/中,测试代码(OCUnit等)放在test/中,所有资源(NIB/XIB文件、Info.plist、图像等)放在resources/中,等等。如果您正在开发一个复杂的项目,根据功能将源代码分组到目录层次结构中可能是一个不错的解决方案。无论如何,良好组织的项目目录可以更容易地找到所需的内容。
Xcode实际上并不关心文件的位置。项目侧边栏中的组织完全独立于磁盘位置,它是一种逻辑(而不是物理)分组。您可以根据自己的喜好在侧边栏中组织,而不会影响磁盘位置,这在源代码存储在版本控制中时很好。另一方面,如果您在磁盘上移动文件,修复Xcode引用是一项手动而繁琐的任务,但可以完成。最好是从一开始就创建好您的组织,并在它们所属的目录中创建文件。
我的观点:虽然拥有包/命名空间机制可能很好,但不要指望它会发生。实际上,类冲突在实践中非常罕见,一旦发生就会非常明显。命名空间在Objective-C中实际上是解决一个不存在的问题。(此外,添加命名空间将使前缀等解决方案变得多余,但可能会在方法调用等方面引入更多复杂性。)
更加微妙和狡猾的错误来自方法冲突,当方法被添加和/或被子类覆盖时,不仅是通过子类,还可能是通过分类,这可能会导致严重的错误,因为分类的加载顺序是未定义(不确定的)。实现分类是Objective-C中最棘手的部分之一,只有当您知道自己在做什么时才应该尝试,特别是对于第三方代码,尤其是对于Cocoa框架类。
所以你是在说Xcode中的逻辑组织,与磁盘位置无关,更多是为了开发者方便,是唯一的组织类的方法吗?
Objective-C中没有像Java中的包一样的概念,这导致了一些问题,例如使用较长的名称来区分不同的类和功能。这使得代码变得冗长,不易阅读和维护。以下是一些讨论和文章,探讨了Objective-C中命名和编码风格的问题,以及是否需要引入命名空间的讨论。
其中一篇文章《Article on coding style & naming in Cocoa / Objective-C》提到了Cocoa / Objective-C中的命名和编码风格的问题。这篇文章指出,Objective-C中的命名习惯较长,常常需要使用多个单词来描述一个类或方法的功能,这是为了保持代码的可读性和一致性。然而,这也导致了代码的冗长和复杂性。
另一篇讨论《Discussion whether Obj-C needs namespaces》(已删除,存档链接在这里)探讨了是否需要在Objective-C中引入命名空间的问题。命名空间可以帮助解决代码命名冲突的问题,使得不同的类和功能可以被更清晰地组织和区分。然而,这篇讨论的链接已经失效,但是通过存档仍然可以查看到其中的内容。
不幸的是,dotnetdevelopersjournal.com这个网站已经关闭。但是,感谢提供了一个存档链接,虽然外观不太好看,但是其中的文本内容仍然可以查看到。
Objective-C中缺乏类似Java中包的概念,导致了一些命名和组织代码的问题。为了解决这些问题,一些文章和讨论提出了不同的观点,例如使用更长的名称来保持代码的可读性和一致性,以及引入命名空间来组织和区分不同的类和功能。然而,目前Objective-C还没有引入命名空间的功能,这也导致了一些代码管理上的困难。
Objective-C与Java的一个主要区别是它没有命名空间的概念。这导致了在Objective-C中处理命名冲突的困难,需要使用一些痛苦的技巧来解决。
在Stack Overflow的一个讨论中,有人提出了一个关于如何解决Objective-C命名空间冲突的问题。该讨论提供了一种解决方法,即使用一些繁琐的技巧来模拟命名空间。
在Objective-C中,可以使用前缀来给类和函数命名,以避免与其他库或代码中的命名冲突。例如,在一个名为"MYFramework"的框架中,可以将所有的类和函数命名为"MYClass"、"MYFunction"等。这样,即使在其他库或代码中有相同的类或函数名,也不会发生冲突。
另一种解决方法是使用Objective-C的类别(Categories)来模拟命名空间。类别可以为现有的类添加新的方法,从而在不修改原始类的情况下扩展其功能。通过将类别与前缀结合使用,可以实现类似于命名空间的效果。
在Objective-C中,还可以使用模块(Modules)来组织代码并避免命名冲突。模块是一种将相关的代码组织在一起的方式,可以将其导入到其他文件中使用。通过使用模块,可以将相关的类和函数放在同一个模块中,并使用命名空间来避免冲突。
总结起来,Objective-C没有像Java那样的命名空间概念,这导致了在Objective-C中处理命名冲突的困难。为了解决这个问题,可以使用前缀、类别或模块等技巧来模拟命名空间。这些技巧可以帮助开发人员避免命名冲突,并使代码更加清晰和可维护。