A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

适合java基础的同学迅速了解OC

  1. #import <Foundation/Foundation.h>

  2. 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. */
复制代码

[size=17.77777862548828px]
Class类型:

[size=17.77777862548828px]typedef struct objc_class{
....
} *Class


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


NSObject中class方法实现伪代码:

-(Class)class
{
return self->isa;
}


+(Class)class
{
return self;
}


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




类的加载和初始化:

//类按从父类到子类的顺序加载
//当程序启动,加载一次项目中所有的类,在类加载完后调用load方法(只加载一次)
//类与分类是分别加载,所有类与分类中的load方法都会被调用
+(void)load
{
//doSomething
}


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












SEL类型:
typedef struct objc_selector{
.....
} *SEL


1>方法调用的消息机制中,消息即SEL
2>OC中每个方法类的方法都存在类对象中,每个方法都有一个与之对应的SEL类型对象
3>每个方法的参数列表中都有一个SEL类型的隐藏参数_cmd,代表当前方法的SEL
4>方法调用过程:
将方法名包装成SEL类型数据
跟据SEL数据找到对应的方法地址
根据方法地址调用方法

将方法名包装成SEL:
SEL s=@selector(test);
将方法名的OC字符串包装成SEL:
SEL s=NSSelectorFromString(@"test");
从SEL中获取方法名的OC字符串:
NSString *str=NSStringFromSelector(s);


方法调用其他形式:
[p test] 等价于 [p performSelector:@selector(test)];

[p test:@"aaaaa"]等价于[p performSelector:@selector(test:) withObject:@"aaaaa"];



description方法:(NSObject的方法,类似java中toString)
%@输出格式,即调用OC对象的description方法后输出返回的NSString*

[size=17.77777862548828px]
NSObject中实现的伪代码:

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


+ (NSString *)description
{
return [self className];
}


1 个回复

正序浏览
晕,有写符号自动转换成表情了,这怎么破;
看来还是要全部写在代码里面比较合适
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马