黑马程序员——OC中的类

来源:互联网 发布:卖家怎么玩好淘宝客 编辑:程序博客网 时间:2024/05/21 20:02
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

一、类的本质

类本身也是一个对象,是class类型的对象,简称“类对象”。
Class类型的定义:
Typedef struct obj class *class;

类名就代表着类对象,每个类只有一个类对象。

获取内存中的类对象有两种方法:
(1)class c=[p cla
ss];//指向类的对象的指针调用class方法
(2)
class c1=[Person class];//使用类名调用class方法

[objc] view plaincopy
  1. //头文件  
  2. #import<Foundation/Foundation.h>  
  3. #import "class1.h"  
  4.   
  5. int main() //函数入口点  
  6. {  
  7.   //创建一个person对象  
  8.    Person *p=[[Person alloc] init];  
  9.  //调用p的class方法  
  10.    class c1=[p class];  
  11.    //调用类class1 的class方法  
  12.    class c2=[class1 class];  
  13.   //打印三者地址值  
  14.    NSLog(@"\n%p\n%p\n%p",p,c1,c2);  
  15. return 0;  
  16. }  
二、类的加载
[objc] view plaincopy
  1. //Person类的实现  
  2. #import "Person.h"  
  3. @implementation Person  
  4. //重写load方法  
  5. + (void)load  
  6. {  
  7.     NSLog(@"class --load");  
  8. }  
  9. //重写initialize方法  
  10. + (void)initialize  
  11. {  
  12.     NSLog(@"class ---initialize");  
  13. }  
  14. @end  
[objc] view plaincopy

  1. #import <Foundation/Foundation.h>  
  2. #import "Person.h"  
  3. int main()  
  4. {  
  5.     return 0;  
  6. }  
由上我们可以看出,程序运行时会加载类的load方法.
当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次;

三、类的初始化
[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2. #import "Person.h"  
  3. int main() //入口点  
  4. {  
  5.    //创建一个Person类  
  6.     Person *p=   [[Person alloc]init];  
  7.     return 0;  
  8. }  
对比我们可以知道,当程序运行时会加载load方法,当使用时会加载initialize方法.
当第一次使用某个类时,就会调用当前类的+initialize方法;
先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法,最后调用分类的+load方法),先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)。
注意:在初始化的时候,如果在分类中重写了+initialize方法,则会覆盖掉父类的。
重写+initialize方法可以监听类的使用情况。

四、description方法
-description方法

使用NSLog%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出.

[objc] view plaincopy
  1. #import <Foundation/Foundation.h>  
  2. #import "Person.h"  
  3. int main()  
  4. {  
  5.     Person *p1=[[Person alloc]init];  
  6.     //以%@输出p1  
  7.     NSLog(@"%@",p1);  
  8.     return 0;  
  9. }  
  10. //输出结果  
  11. faceOfClass[29629:110095] <Person: 0x10030e270>  
重写-description
[objc] view plaincopy
  1.  #import "Person.h"  
  2. @implementation Person  
  3. //重写description方法  
  4. - (NSString *)description  
  5. {  
  6.     NSLog(@"调用了description方法");  
  7.     return @"just test";  
  8. }  
  9. @end  
由此我们可以看出
使用NSLog%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出.
五、SEL
SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法,其实消息就是SEL.   
每个类的方法列表都存储在类对象中,每个方法都有一个与之对应的SEL类型的对象,根据一个SEL对象就可以找到方法的地址,进而调用方法.
SEL类型的定义
       typedef struct objc_selector *SEL;

SEL对象创建
1.SEL s = @selector(test);
2.SEL s2 = NSSelectorFromString(@"test");
SEL对象的其它用法
[objc] view plaincopy
  1. // 将SEL对象转为NSString对象  
  2. NSString *str = NSStringFromSelector(@selector(test));  
  3. //练习  
  4.  SEL s1=@selector(test);  
  5.     NSLog(@"%@",NSStringFromSelector(s1));  
  6. //输出结果为test  
SEL的使用

[objc] view plaincopy
  1. Person *p = [Person new];  
  2. // 调用对象p的test方法  
  3. [p performSelector:@selector(test)
0 0