充分利用Objective-C动态特性

Ian*_*971 12 objective-c

我一直在使用Objective-C但是来自静态类型背景(C#)我想我是以非常静态的方式使用它.将对象声明为id对我来说感觉陌生,我看不出有什么好处.任何人都能为我发光,以便更好地了解这一点吗?

Adr*_*ski 13

Objective-C是一种混合语言,您可以根据需要动态和静态地使用它.如果需要,可以声明所有变量的所有类型,如果需要,甚至可以将委托变量声明为NSObject <Protocol>*.id类型作为一个真正的类型工作较少,更像是编译器告诉他"嘿,我知道我在做什么,只相信我",使编译器避免对该特定变量进行任何类型检查.

Objective-C类型系统的第一个明显好处是容器类型(NSArray,NSDictionary,NSSet)接受并返回id类型.这样就完全不需要模板和泛型(比如在C++,Java和C#中).

更好的是,你实际上可以在里面放置任何类型元素的容器.只要你知道里面有什么,如果你在同一个NSArray中添加两个NSStrings,一个NSNumber和一个NSValue,没有人会抱怨.您可以使用其他语言执行此操作,但必须使用"Object"基类或void*类型,然后您需要对变量进行包装和取消(或向上和向下)以获得相同的行为.在Objective-C中你只需要分配,它可以消除由于施放操作符和装箱操作而产生的噪音.然后,您可以向每个对象询问"respondsToSelector:"或"class",以便在运行时了解您可以使用它们执行的标识和操作.在Objective-C中,反思是一流的公民.

另一个好处是减少了编译时间; 一般来说,Objective-C程序的编译比它在C++中的等价程序要快得多,因为没有执行那么多的类型检查,并且在运行时进行了很多链接.编译器更信任程序员.

最后,Objective-C的动态类型系统可以使用Interface Builder之类的工具.这是Cocoa和Cocoa Touch开发时间更快的主要原因; GUI可以在整个地方生成具有"id"类型的代码,只要NIB加载到内存中,就会反序列化.在UI设计体验方面,唯一接近Objective-C的语言是C#(当然还有VB.NET),但代价是更重的应用程序.

我个人更喜欢使用更静态的类型检查,我甚至打开Objective-C编译器中的"将警告视为错误"设置; 我写了一篇关于它的博客文章:

http://akosma.com/2009/07/16/objective-c-compiler-warnings/

当您与不熟悉该语言的开发人员合作时,这尤其有用.它使编译器比平常更常呜呜:)

静态类型系统专家可能不同意所有这些观点,认为静态类型检查允许"智能感知"IDE和更好的维护.我使用.NET多年(2001年至2006年),我必须说动态语言往往产生更少的代码,更容易阅读,并且通常可以提供更多的工作自由.权衡(总是存在权衡)是编译时信息较少.但正如我倾向于说,编译器是一个穷人的测试套件.恕我直言,最好的事情是拥有一套完善的测试,以及一大堆人类测试人员折磨代码以查找错误,无论您选择何种语言.


Yuj*_*uji 5

Objective-C的活力不仅仅体现在每个物体都是一个物体的事实上id.相反,它充分发挥了Objective-C运行时的强大功能和易用性.Apple自身巧妙运用运行时的几个例子:

DO允许您在单独的应用程序/单独的计算机中为Obj-C对象设置代理对象.这是通过拦截发送到代理对象的所有消息,将其打包,将其发送到另一个应用程序并在那里调用它来完成的.

通过动态替换setter方法实现KVO,以便它自动通知观察者.(嗯,事实上它比...更微妙)

CoreData访问器在运行时为每个子类NSManagedObject等生成.

而且,您也可以使用代码中的运行时.我曾经使用它来获得良好的效果,模仿CoreData并在运行时生成访问器,并且只在头文件中声明它们.因此,您可以获得静态类型(标头中的声明的编译时错误)和动态(运行时生成方法)的优点.

Mike Ash撰写了一系列关于运行时如何工作以及如何有效使用它的博客文章.你只需要阅读它!DO,KVO,消息转发等.也有在网上许多其他有趣的帖子,像用KVC乐趣和更高阶的消息1,2.