技术开发 频道

为C++编程者开发的Objective-C高级篇

  【IT168技术】David Chisnall以探索Objective-C语言更多的一些高级概念来总结他的三部分。在这个系列的第一部分,我们看到了Objective-C语言的核心。第二部分,我们看到了Objective-C语言的定义类、创建对象和给他们传送消息。最后一部分涵盖了这个语言的更多高级部分。

  内省

  C++通过运行时类型信息(RTTI)支持内省。虽然是通过编译器不完全支持;甚至在支持的地方也不会真正的用到,是基于性能原因。相反,内省信息在Objective-C中是可获得的。

  类结构包含一个链表或关于方法和其他实例变量的元数据数组。每一个实例变量包含从对象起始得到的偏移、类型、名字。你可以通过这个设置做一些有趣的事。举例来说,我曾经编写一个étoilé的框架来回顾这些信息并用它们来自动序列化一些对象(仅在C++下对那些你有源代码的对象)。对于方法,它有名字,类型和实现方法的函数指针。这是一个实例方法指针,并且在头部如下定义:

  Typedef id(*IMP)(id,SEL,…);这里使用了其它两种Objective-C类型。id类型是指向某种对象的指针。所有你对id的了解就是它来回应消息(虽然你不知道是什么消息,除非你询问一下)。另一种类型就是SEL,一种选择器类型。

  你可以这样做:

  IMP method = [object methodForSelector:@selector(doSomething)];变量方法是一个C函数指针指向方法的实现。如果你发送相同的消息给对象,你可以通过这种性能获得额外的速度。

  因为你可以在运行时构造选择器,你可以对一些动态行为使用这种方式。在XML语法分析器中,当对对象封装一个XML对象的子元素时我使用这种方式。父类实现-addChild:forKey:方法包含下列代码。

  NSString * childSelectorName = [NSString stringWithFormat:@"add%@:", aKey];

  SEL childSelector
= NSSelectorFromString(childSelectorName);

  
if([self respondsToSelector:childSelector])

  {

  [self performSelector:childSelector withObject:aChild];

  }

  这从键名中构建了一个选择器并且和对象一起调用。这种技术被用在XMPP实现。举例来说,标签可以通过一个类来分析,这个类收集字符数据并返回一个字符串。当收到,它操作如下:

  [parent addChild:string forKey:@"name"];

  parent运行这个方法,调用-addname:带字符串的方法作为一个参数。更复杂的格式在Cocoa的键-值代码中实现,这内省了方法和实例变量的元数据。当你调用-setValue:forKey:它将调用一个setter,直接设置了一个实例变量,或者调用-setValue:forUndefineKey:。使用键-值代码比设置实例变量或调用set/get方法速度要慢,但是可以完全从接口的实现中分离出来。

  随着Objective-C2.0的出现,Apple引进了属性、存储这种方式:

  object.property = 12;这是语法糖的非常薄的一层。内部来说,他们翻译成set和get是基于属性的使用。属性最好的特性就是他们允许set和get方法由任何一个给出的实例变量自动产生,随着retain,assign和copy语法。

0
相关文章