IOS基础之 (七) 分类Category

一 Category

分类:Category(类目,类别) (OC有)

命名:原来的类+类别名(原来的类名自动生成,只要写后面的类别名,一般以模块名为名。比如原来类 Person,新建分类 Ct,新建的分类名为 Person+Ct )

作用: 在不改变原来类的内容的情况下,可以给原来的类添加一些新的方法

注意:

1)分类只能增加方法,不能增加成员变量。

2)分类方法的实现中,可以访问原来类中的成员变量。

3)分类可以重写原来类的方法。但是会覆盖原来类的方法(一般不会再分类当中重写原来类的方法)。

4)调用优先级:分类优先(最后参与编译的分类会优先调用)。

1. 创建一个OC类

New File -> iOS -> CoCoa Touch Class ,新建一个类 Person

 Person.h

1 #import <Foundation/Foundation.h>
2 
3 @interface Person : NSObject
4 
5 @property int age;
6 
7 - (void) showInfo;
8 
9 @end

 Person.m

 1 #import "Person.h"
 2 
 3 @implementation Person
 4 
 5 - (void)showInfo{
 6     NSLog(@"人的年龄是%d", _age);
 7     
 8 }
 9 
10 @end

2. 新建一个分类

New File -> iOS -> CoCoa Touch Class ,新建一个分类 Ct1 ,File Type选择 Category ,Class 填为 Person (表示的是Person类的分类)

   Person+Ct1.h

1 #import "Person.h"
2 
3 @interface Person (Ct1)
4 
5 - (void) run;
6 
7 @end

   Person+Ct1.m

1 #import "Person+Ct1.h"
2 
3 @implementation Person (Ct1)
4 
5 - (void)run{
6     NSLog(@"调用了 run()方法");
7 }
8 @end

3.测试

main.m

 1 #import <Foundation/Foundation.h>
 2 #import "Person.h"
 3 #import "Person+Ct1.h"
 4 
 5 int main(int argc, const char * argv[]) {
 6     Person *p = [[Person alloc]init];
 7     p.age = 20 ;
 8     [p showInfo];
 9     [p run];
10        
11     return 0;
12 }

第2行: 导入Person类的头文件。

第3行:导入Person的分类头文件。

第9行是:person 对象调用的分类方法 run。

二 类的本质

1.类的本质是类本身也是一个对象,是个Class类型对象,简称类对象。

利用Class创建Person类对象。

利用Person类对象 ,创建Person类型的对象。

 1.1获取内存中的类对象

Class c =[p class];
Class c2 =[p2 class];

 1.2获取内存中的类对象

Class c3 = [Person class]

 当程序启动时,就会加载一次项目中所有的类。类加载完之后,就会调用这个+load方法。(分类,本身类程序启动时都会调用,)

必须使用类,当类第一次使用时调用,就会调用 + initialize方法。(分类,本身类,有分类只会调用分类)

先加载父类的,在加载子类的(先调用父类的 +load,在调用子类的 +load ) 

先调用父类的初始化方法,在调用子类的初始化方法( + initialize)。

 

面试题:监听什么时候调用这个类,使用的方法。

+ (void) initialize{
}

三 description

重写对象的字符串输出。

 

四 SEL

 SEL:全称Selector 表示方法的存储位置

Person *p=[[Person alloc] init];
[p test];

 寻找方法的过程:

(1)首先把test这个方法名包装成sel类型的数据;

(2)根据SEL数据找到对应的方法地址;

(3)根据方法地址调用相应的方法。

(4)注意:在这个操作过程中有缓存,第一次找的时候是一个一个的找,非常耗性能,之后再用到的时候就直接使用。

注意:SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去寻找对应的方法地址,找到方法地址后就可以调用方法。这些都是运行时特性,发消息就是发送SEL,然后根据SEL找到地址,调用方法。

 Person.h

1 #import <Foundation/Foundation.h>
2 
3 @interface Person : NSObject
4 
5 @property NSString *name;
6 @property int age;
7 
8 - (void) run;
9 - (void) showAge:(int)age WithName:(NSString *)name ;

Person.m

 1 #import "Person.h"
 2 
 3 @implementation Person
 4 
 5 - (void)run{
 6     NSLog(@"名字是%@,年龄是%d的人正在跑步。", _name, _age);
 7     
 8 }
 9 
10 - (void)showAge:(int)age WithName:(NSString *)name{
11 
12     NSLog(@"age=%@,name=%@",age,name);
13 }
14 
15 @end

测试 @selector

Person *p = [[Person alloc]init];
p.name = @"wangwu";
p.age = 20;
    
NSObject *age1 = @20;
id age2 = @21;
[p performSelector: @selector(showAge:WithName:) withObject: age1 withObject: @"lisi" ];

 

五 NSLog

 

 1  Person *p1= [Person alloc];
 2 
 3     //<类名: 内存地址>
 4     NSLog(@"%@", p1);
 5     
 6     // 指针变量的地址
 7     NSLog(@"%p", p1);
 8     
 9     //打印对象的地址
10     NSLog(@"%p", &p1);
11     
12     //输出行号
13     NSLog(@"%d" , __LINE__ );
14     
15     //输出C语言中的字符串,不能有中文
16     NSLog(@"%s" , __FILE__);
17     
18     //输出C语言中的字符串,可以有有中文
19     printf("%s\n", __FILE__);

 

 

引用博客:

http://www.cnblogs.com/wenxp2006/archive/2012/05/14/2499329.html

http://www.cnblogs.com/qingyuan/p/3618305.html

http://www.cnblogs.com/qingyuan/p/3617086.html

posted @ 2016-02-17 00:21  陈晓楠  阅读(332)  评论(0编辑  收藏  举报