一 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 ", __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