黑马程序员技术交流社区

标题: OC学习笔记06--OC运行时中类的加载、初始化 和方法调用机... [打印本页]

作者: wowthe1st    时间: 2015-7-31 13:53
标题: OC学习笔记06--OC运行时中类的加载、初始化 和方法调用机...
本帖最后由 wowthe1st 于 2015-7-31 13:57 编辑
  1. #import <Foundation/Foundation.h>

  2. void printMethodInfo(id self,Class clz,SEL _cmd,int line)
  3. {
  4.         NSLog(@"调用者=%@,当前类=%@,调用方法=%@,行数=%d",
  5.         self,[clz className],NSStringFromSelector(_cmd),line);
  6. }
  7. // SuperClass
  8. @interface SuperClass : NSObject
  9. @end

  10. @implementation SuperClass

  11. + (void)load
  12. {
  13.         printf("当前所在文件:%s,",__FILE__);// %s输出char*,若遇到中文在NSLog中将无法输出,改成利用printf输出
  14.         //第一次调用SuperClass时,会进行初始化,初始化只进行一次
  15.         NSLog(@"调用者=%@,当前类=%@,调用方法=%s,当前行数=%d",self,[SuperClass className],__func__,__LINE__);
  16.         
  17. }

  18. + (void)initialize
  19. {
  20.         printMethodInfo(self,[SuperClass class],_cmd,__LINE__);
  21.         
  22. }
  23. @end

  24. // SubClass
  25. @interface SubClass : SuperClass
  26. @end

  27. @implementation SubClass

  28. + (void)load
  29. {
  30.         printMethodInfo(self,[SubClass class],_cmd,__LINE__);
  31. }

  32. + (void)initialize
  33. {
  34.         printMethodInfo(self,[SubClass class],_cmd,__LINE__);
  35. }
  36. @end

  37. // SubClass (Category)
  38. @interface SubClass (Category)
  39. @end

  40. @implementation SubClass (Category)

  41. //分类与本类的load方法都被调用,说明分类与本类是分别加载的
  42. + (void)load
  43. {
  44.         printMethodInfo(self,[SubClass class],_cmd,__LINE__);
  45. }


  46. //从行号可以看出,分类与本类只调用了分类的初始化方法,说明分类初始化方法覆盖了本类
  47. + (void)initialize
  48. {
  49.         printMethodInfo(self,[SubClass class],_cmd,__LINE__);
  50. }
  51. @end

  52. int main()
  53. {
  54.         SubClass * subclz=[[[SubClass class] alloc] init];
  55.         //%@打应对象,会先调用对象的description方法返回NSString*后输出,
  56.         //NSObject中该方法实现为返回<类名: 指针值>
  57.         //重写该方法返回想要的值
  58.         NSLog(@"subclz=%@,指针值=%p",subclz,subclz);
  59.         
  60.         NSLog(@"subclz=%@,指针值=%p",[subclz description],subclz);
  61.         
  62.         NSLog(@"subclz=%@,指针值=%p",[subclz performSelector:@selector(description)],subclz);
  63.         
  64.         NSLog(@"subclz=%@,指针值=%p",[subclz performSelector:NSSelectorFromString(@"description")],subclz);
  65.         
  66.         //上面调用的四中方式是等效的
  67.         
  68.         return 0;
  69. }


  70. /*
  71. NSLog:
  72.         输出char*时,不允许有中文
  73. __func__  当前函数签名 %s
  74. __LINE__  当前行号 %d
  75. __FILE__  当前文件路径 %s
  76. */

  77. /*


  78. Class类型
  79. typedef struct objc_class{
  80.         ....
  81. } *Class

  82. Class类也继承NSObject,而且类加载后的类对象(即Class类的实例)中的isa指针指向Class类

  83. NSObject中class方法实现伪代码:
  84. -(Class)class
  85. {
  86.         return self->isa;
  87. }

  88. +(Class)class
  89. {
  90.         return self;
  91. }

  92. id *p=[[[NSObject class] alloc] init] 等价于[[NSObject alloc] init]


  93. 类的加载和初始化:
  94. //类按从父类到子类的顺序加载
  95. //当程序启动,加载一次项目中所有的类,在类加载完后调用load方法(只加载一次)
  96. //类与分类是分别加载,所有类与分类中的load方法都会被调用
  97. +(void)load
  98. {
  99.         //doSomething
  100. }

  101. //类按从父类到子类的顺序初始化
  102. //当程序中第一次使用某个类时调用其initialize方法,只初始化一次
  103. //类与分类是一起初始化,分类的initialize方法会覆盖类中的该方法
  104. + (void)initialize
  105. {
  106.         //doSomething
  107. }



  108. SEL类型:
  109. typedef struct objc_selector{
  110.         .....
  111. } *SEL

  112. 1>方法调用的消息机制中,消息即SEL
  113. 2>OC中每个方法类的方法都存在类对象中,每个方法都有一个与之对应的SEL类型对象
  114. 3>每个方法的参数列表中都有一个SEL类型的隐藏参数_cmd,代表当前方法的SEL
  115. 4>方法调用过程:
  116.                 将方法名包装成SEL类型数据
  117.                 跟据SEL数据找到对应的方法地址
  118.                 根据方法地址调用方法
  119.                
  120. 将方法名包装成SEL:
  121. SEL s=@selector(test);
  122. 将方法名的OC字符串包装成SEL:
  123. SEL s=NSSelectorFromString(@"test");
  124. 从SEL中获取方法名的OC字符串:
  125. NSString *str=NSStringFromSelector(s);

  126. 方法调用其他形式:
  127. [p test] 等价于 [p performSelector:@selector(test)];
  128.         
  129. [p test:@"aaaaa"]等价于[p performSelector:@selector(test:) withObject:@"aaaaa"];
  130.         
  131.         
  132.         
  133. description方法:(NSObject的方法,类似java中toString)
  134. %@输出格式,即调用OC对象的description方法后输出返回的NSString*
  135. NSObject中实现的伪代码:

  136. - (NSString *)description
  137. {
  138.         return [NSString stringWithFormat:@"<%@: %p>",[self class],self];
  139. }

  140. + (NSString *)description
  141. {
  142.         return [self className];
  143. }

  144. */
复制代码
刚才发的一份出现错误了,重发一份





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2