iOS开发之oc(十)--类的本质、description、SEL

(一)类的本质

1.类也是个对象

其实类也是一个对象,是Class类型,简称“类对象”。

// Class类型的定义
typedef struct objc_class *Class;
// 类名就代表着类对象,每个类只有一个类对象

2.+load和+initialize

  • +load

>  在程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法

>先加载父类,再加载子类;也就是先调用父类的+load,再调用子类的+load

>先加载元原始类,再加载分类

>不管程序运行过程有没有用到这个类,都会调用+load加载

  • +initialize

>在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法

>一个类只会调用一次+initialize方法,先调用父类的,再调用子类的

代码示例
// 当程序启动的时候,就会加载一次项目中所有的类。类加载完毕后就会调用+load方法
+ (void)load
{
    NSLog(@"Person---load");
}

// 当第一次使用这个类的时候,就会调用一次+initialize方法
+ (void)initialize
{
    NSLog(@"Person-initialize");
}

@end

 

3.获取类对象的两种方式

Class c = [Person class];    //  类方法
// 或者
Person *p = [Person new];
Class c2 = [p class];     //  对象方法

4.类对象调用类方法

Class c = [Person class];
Person *p2 = [c new];

(二)description方法

(决定了实例对象/类对象的输出结果)

1. -description方法

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

1. + description方法

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

2. 修改NSLog的默认输出

问题出现

int main()
{
    Person *p = [[Person alloc] init];
    NSLog(@"%@",p);
    
    return 0;
}    

输出为:<Person: 0x1001033b0>   是个地址,要想输出具体内容

 

 重写-description或者+description方法即可

3. 死循环陷阱

如果在-description方法中使用NSLog打印self

(三)SEL

/*
 SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。
   找到方法地址就可以调用方法
 其实消息就是SEL
 

原理  // 1.把某个方法例如test包装成SEL类型的数据

    // 2.根据SEL数据找到对应的方法地址

    // 3.根据方法地址调用对应的方法

*/

 

1.方法存储的位置

>每个类的方法列表都存储在类对象中

>每个方法都有一个与之对应的SEL类型的对象

>根据一个SEL对象就可以找到方法的地址,进而调用方法

>SEL类型的定义

typedef struct objc_selector    *SEL;

2.SEL对象的创建

SEL s = @selector(test);

SEL s2 = NSSelectorFromString(@"test");

3.SEL对象的其他用法

代码示例

调用方法有两种途径:
1直接通过方法名
[p test2]
2传入方法对应的SEL去找方法地址
   // 间接调用test方法
    [p performSelector:@selector(test)];
3)对象方法要传(带)参时    
     [p test:@"123"];   
等同下面( SEL的创建   SEL s = @selector(test:);   )
     [p performSelector:@selector(test:) withObject:@"456"];

1>把字符串变成SEL
SEL s = NSSelectorFromString(@"name");

2>把SEL对象变成字符串NSString对象
 _cmd代表着当前方法(  _cmd==@selector(test);   )
NSString *str = NSStringFromSelector(@selector(test));
NSString *str = NSStringFromSelector(_cmd);

补充:
每个方法内部都有一个隐藏的sel数据:   _cmd(SEL)代表当前方法
死循环
- (void)test
{
    // _cmd代表着当前方法  
    // 会引发死循环
    [self performSelector:_cmd];
    
}

 

posted @ 2015-02-24 17:06  timo1234  阅读(223)  评论(0编辑  收藏  举报