Objective-C中的NSObject对象经常使用到的方法

来源:互联网 发布:梵语发音软件 编辑:程序博客网 时间:2024/06/05 15:15

Objective-C中的NSObject对象经常使用到的方法

2012-04-20 09:22:05|  分类:iphone学习|字号订阅

/*
用于判断对象是不是参数提供的类型(参数可以是父类的class) 
参数示例: [NSObject class];
*/
- (BOOL)isKindOfClass:(Class)aClass;


/*
用于判断对象是不是参数提供的类型(参数不可以是父类的class) 
参数示例: [NSObject class];
*/
- (BOOL)isMemberOfClass:(Class)aClass;


/*
用于判断对象是否遵守了参数提供的协议 
参数示例: @protocol(UIApplicationDelegate)
*/
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;


/*
用于判断对象是否拥有参数提供的方法 
参数示例: @selector(test) or @selector(testById:)
*/
- (BOOL)respondsToSelector:(SEL)aSelector; 


/*
延迟调用参数提供的方法,参数所需参数用withObject传入(类似于ActionScript3.0中的setTimeout函数)
delay单位:秒
*/
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;


SObject协议组对所有的Object-C下的objects都生效。

如果objects遵从该协议,就会被看作是first-class objects(一级类)。

另外,遵从该协议的objects的retain,release,autorelease等方法也服从objects的管理和在Foundation中定义的释放方法。一些容器中的对象也可以管理这些objects,比如

说NSArray 和NSDictionary定义的对象。

Cocoa的根类也遵循该协议,所以所有继承NSObjects的objects都有遵循该协议的特性。


NSObjects采用的协议:

NSObject

  • autorelease
  • class
  • conformsToProtocol:
  • description
  • hash
  • isEqual:
  • isKindOfClass:
  • isMemberOfClass:
  • isProxy
  • performSelector:
  • performSelector:withObject:
  • performSelector:withObject:withObject:
  • release
  • respondsToSelector:
  • retain
  • retainCount
  • self
  • superclass
  • zone

NSObject是大多数Objective-C类的继承的根类;它没有父类。通过NSObject,其它类继承了一些基础的与Objective-C语言编译器系统之间的接口,并且获得了在它的实例中表现为一个对象的能力。

尽管NSObject不是一个严格的抽象类,实际上它已经是一个类。但是通过它自己一个除了表现为一个简单类之外,NSObject实际上几乎无法完成任 何有用的操作。为你的程序添加任何属性(attributes)并制定实现逻辑,你必须创建一个或者多个从NSObject继承或者父类从 NSObject继承的类(class)。

NSObject采用(adopts,或者说是继承实现)了NSObject协议(protocol)(见“Root Class—and Protocol”(第67页) ) 。NSObject协议(protocol)允许被多个根类(root class)采用,比如NSProxy另一根类(root class),并不是从NSObject继承,但却也采用了NSObject协议(protocol)所以它在Objective-C中便有了和NSObject类相似部分的类的定义(interface)和功能。


NSObject根类,和采用了NSObject协议或者其它根类协议(“root” protocols)一道,为所有的非代理(non-proxy)Cocoa对象指定了以下的定义(interface)和特有的事件:

■Allocation, initialization, 和 duplication。一些NSObject方法(包括一些采用的协议)用来处理创建(creation),初始化(initialization)和复制(duplication)对象。

?alloc和allocWithZone:方法在内存中为一个对象分配了内存空间并且设置它指向的对象的编译器类定义(即是告诉编译器定义了一个类,译者注)。

?init方法为对象的属性初始化(prototype),一个让实例变量初始化状态的进程。类方法中的initialize和load让一个类有机会初始化它们自己。

?new一种方便的结合分配内存和初始化的方法。

?copy和copyWithZone:方法复制任意对象的内存的实现方法(从NSCopying协议来的);mutableCopy和mutableCopyWithZone:(在NSMutableCopying协议中定义)将被应用于(mplemented by)该类来完成不定的对象拷贝(make mutable copies of their objects)。


■Object retention and disposa(对象的保留和释放)。接下来的方法对于面向对象的程序尤其的重要,那就是如何传统的,明确的,形式化的(traditional, and explicit, form)实现内存管理。

?retain方法,增加对象的计数器。

?release方法,减少对象的计数器

?autorelease方法,自动减少对象的计数器,但是以推迟的方式来实现。

?retainCount方法,返回一个对象当前的计数器

? dealloc方法应用于类来释放对象实例变量并释放动态内存。


■ Introspection 和 comparison(反省机制和对比机制).许多NSObject方法使你能够让编译器查询一个对象。反省方法(introspection methods)帮助你探查一个对象在类继承机制中的位置,决定是否实现一些方法,并测试它是否遵循一些协议。而一些类仅是有一些方法。

?superclass和class方法(类和实例(class and instance))分别返回接收器的父类和类,作为一个Class对象。

? isKindOfClass:和isMemberOfClass:,通过这两种方法可以确定一个类的从属关系。后者测试一个接收器是否是一个指定类的实例;而后者可以测试类的从属关系。

? respondsToSelector: 方法测试一个接收器是否通过selector实现(implements)了一个标志符话的方法。而instancesRespondToSelector:测试了一个给定的类实例化之后(这个消息的接收方法为静态方法,译者注)是否实现了一个指定的方法。

?conformsToProtocol:方法,测试接收器(对象或者类)符合一个给定的协议(protocol)。

? isEqual: 和 hash方法,用于对象比较。

? description方法,允许一个对象返回一个字符串来描述它的内容;这个常用于调试debugging (“print  object”命令 ) 。通过“%@”以字符串输出特殊的指定对象。(即是以NSLog的形式输出,译者注)

参见 “Introspection”(页87)以获取更多的信息

■ Object encoding and decoding(对象的编码和解码).接下来的方法将与对象的编码和解码方式有关 (作为一个归档处理的一部分):

?encodeWithCoder: 和 initWithCoder:方法,NSCoding协议中仅有的组成成员。第一个允许对象编译它的实例变量,第二个允许一个对象初始化它自身的解码实例变量。

?NSObject类声明了一些与对象编码相关的其它方法,有:classForCoder,replacementObjectForCoder:,和awakeAfterUsingCoder:。

参阅Archives and Serializations Programming Guide for Cocoa来获取更多的信息。

■ Message forwarding(消息转发). forwardInvocation:允许一个对象把消息转发给另一个对象。

■ Message dispatch(消息配送). 一个以performSelector...为开头的方法允许你配送消息(message)直到指定的延迟后,并且可以从二级线程((synchronously or asynchronously)同步或者不同步地)配送消息到主线程。

NSObject拥有许多其它的方法,比如版本和传递的类方法(class methods for versioning and posing)(之后将为你展示如何将一个类本身编译为另一个类)。它既包括了方法让你访问编译器数据结构的类,比如selector方法和函数指针形式的方法实现。


  1. #import 
  2. #import "Caller.h"
  3. int main (int argc, constchar *argv[]) {
  4. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  5. /*分析NSObject中的方法*/
  6. Caller *c = [[Caller alloc] init];
  7. NSLog(@"c retain count: %d", [c retainCount]);
  8. Caller *c1 = [[Caller alloc] init];
  9. //1.- (Class) class;            /** See [NSObject-class] */
  10. NSLog(@"class: %@", [c class]);
  11. //2.- (Class) superclass;           /** See [NSObject-superclass] */
  12. //父类是 NSObject
  13. NSLog(@"super class: %@", [c superclass]);
  14. //3.- (BOOL) isEqual: (id)anObject;     /** See [NSObject-isEqual:] */
  15. //从下面的例子可以看出isEqual是比较的地址指针,[c retain]出来的指针是一样的所以相等 c1的指针和c不一样 所以不相等
  16. if ([c isEqual:[c retain]]){
  17. NSLog(@"isEqual [c retain]");
  18. }
  19. NSLog(@"c retain count: %d", [c retainCount]);
  20. if (![c isEqual:c1]){
  21. NSLog(@"is not Equal c1");
  22. }
  23. //4. - (BOOL) isKindOfClass: (Class)aClass; /** See [NSObject-isKindOfClass:] */
  24. if ([c isKindOfClass:[NSObject class]]){
  25. NSLog(@"isKindOfClass NSObject");
  26. }
  27. //5. - (NSUInteger) hash;           /** See [NSObject-hash] */
  28. NSLog(@"%d", [c hash]);
  29. //6. - (id) self;               /** See [NSObject-self] */
  30. //从下面的例子可以看出 self 方法不会增加对象的retainCount, 只是在上面的retain的时候才增加了一个, self方法取得的就是对象本身
  31. Caller *c2 = [c self];
  32. NSLog(@"c retain count: %d", [c retainCount]);
  33. //7.- (BOOL) respondsToSelector: (SEL)aSelector;
  34. //从下面例子可以看出这个方法就是判断某个对象是不是有某个方法
  35. if ([c respondsToSelector:@selector(init)]){
  36. NSLog(@"the c object have init function.");
  37. }
  38. //8.- (id) retain
  39. //引用计数+1
  40. Caller *c3 = [c retain];
  41. NSLog(@"c retain count: %d", [c retainCount]);
  42. //9.- (id) autorelease          /** See [NSObject-autorelease] */;
  43. //从下面的例子可以看出调用autorelease 引用计数不增加
  44. //Caller *c4 = [c autorelease];
  45. //NSLog(@"c retain count: %d", [c4 retainCount]);
  46. //10.+ (id) alloc
  47. //调用alloc 会生成新的对象并且重新分配内存,引用计数会+1
  48. Caller *c5 = [Caller alloc];
  49. NSLog(@"c5 retain count: %d", [c5 retainCount]);
  50. NSLog(@"%@", [c5 description]);
  51. //11. -(id)init
  52. //调用init方法不会生成新的对象,只是返回当前对象本身,引用计数也不会增加.
  53. [c5 retain];
  54. Caller *c6 = [c5 init];
  55. NSLog(@"%@", [c5 description]);
  56. NSLog(@"c6 retain count: %d", [c6 retainCount]);
  57. //12.+ (id) new;
  58. //调用new方法会生成新的对象,并且重新分配内存,并且自动执行对象的init方法.
  59. //所以new = 先执行对象的alloc方法,然后在执行init方法.
  60. Caller *c7 = [Caller new];
  61. [c7 retain];
  62. NSLog(@"%@", [c7 description]);
  63. NSLog(@"c7 retain count: %d", [c7 retainCount]);
  64. //13. - (id) copy;
  65. //如果对象没有实现NSCopying协议而直接copy对象则会出错.
  66. //从下面例子可以看出执行copy方法会生成一个新的对象 并且重新分配内存.实际上就是执行NSCopying协议的copyWithZone方法的结果
  67. Caller *c8 = [c7 copy];
  68. NSLog(@"%@", [c8 description]);
  69. NSLog(@"c8 retain count: %d", [c8 retainCount]);
  70. //  [c8 release];
  71. //14. - (BOOL) conformsToProtocol: (Protocol*)aProtocol
  72. //判断一个class是否实现了某个协议
  73. if ([c8 conformsToProtocol:@protocol(NSCopying)]){
  74. NSLog(@"The Class is conform to NSCopying protocol.");
  75. }
  76. if ([c8 conformsToProtocol:@protocol(NSCoding)]){
  77. NSLog(@"The Class is conform to NSCopying protocol.");
  78. }else{
  79. NSLog(@"The Class is  not conform to NSCopying protocol.");
  80. }
  81. //15.- (NSZone*) zone;          /** See [NSObject-zone] */
  82. //返回一个class的zone, zone是一个结构
  83. NSZone *zone = [c8 zone];
  84. NSLog(@"zone : %@", zone-<name);
  85. //NSZone *nZone = zone-<next;
  86. //NSLog(@"next zone: %@", nZone-<name);
  87. //16. - (NSString*) className;
  88. //返回class name
  89. NSLog(@"class name : %@", [c8 className]);
  90. //17. + (id) allocWithZone: (NSZone*)z;
  91. Caller *c9 = [Caller allocWithZone:[c8 zone]];
  92. NSLog(@"c9 desc : %@", [c9 description]);
  93. NSLog(@"c9 retain count: %d", [c9 retainCount]);
  94. //18. + (IMP) instanceMethodForSelector: (SEL)aSelector;
  95. //此方法返回aSelector的函数指针
  96. IMP imp = [Caller instanceMethodForSelector:@selector(start3)];
  97. id i = imp([Caller new], @selector(start3));//调用函数指针,需要带入参数 (类的实例 方法的名称)
  98. //19. + (NSMethodSignature*) instanceMethodSignatureForSelector: (SEL)aSelector;
  99. //此方法返回一个NSMethodSignature(方法签名?)对象.NSMethodSignature可以用于反射调用
  100. NSMethodSignature *sig = [Caller instanceMethodSignatureForSelector:@selector(start3)];
  101. NSLog(@"numberOfArguments %d", [sig numberOfArguments]);
  102. NSLog(@"methodReturnLength %d", [sig methodReturnLength]);
  103. //反射调用
  104. NSInvocation *ivc = [NSInvocation invocationWithMethodSignature:sig];
  105. [ivc setTarget:[Caller new]];
  106. [ivc setSelector:@selector(start3)];
  107. [ivc invoke];
  108. //20. + (BOOL) instancesRespondToSelector: (SEL)aSelector;
  109. if ([Caller instancesRespondToSelector:@selector(start3)]){
  110. NSLog(@"Caller instancesRespondToSelector start3");
  111. }
  112. if ([Caller instancesRespondToSelector:@selector(start7)]){
  113. NSLog(@"Caller instancesRespondToSelector start7");
  114. }else{
  115. NSLog(@"Caller not instancesRespondToSelector start7");
  116. }
  117. //21. + (BOOL) isSubclassOfClass: (Class)aClass;
  118. //判断是不是子类
  119. if ([Caller isSubclassOfClass:[NSObject class]]){
  120. NSLog(@"Caller isSubclassOfClass of NSObject");
  121. }
  122. //22.  +(void) poseAsClass: (Class)aClassObject;
  123. [Caller poseAsClass:[NSObject class]];
  124. [c1 release];
  125. [c release];
  126. [pool drain];
  127. return 0;
  128. }