OC05核心语法总结 2

来源:互联网 发布:linux命令行下载mysql 编辑:程序博客网 时间:2024/05/20 08:23

六、 分类

知识点

主题1:分类category依赖于类,新建时,创建category模板

1.不改变原来类模型的基础上来扩充方法2.格式:@interface 类名(分类名称) -@end@implementation 类名(分类名称)@end3.调用:首先把相应的头文件包含进来[p study];//和以前调用方式一模样4.如果(庞大的)类方法很多(模块)时,要好多人去写,这时就可以按人去分类,然后调用的时候该咋调用咋调用5.总结:    1)不改变原来类内容的基础上为类增加一些方法。    2)只能增加方法,不能增加成员变量    3)分类的实现是可以访问原来类里的成员变量    4)如果扩充的方法名和原来的方法名一样时(重写),会覆盖原来的方法。因为分类的方法的调用优先级高于原来的类方法,就是先去分类中找,然后再去原来的类去找,最后去父类    5)那如果多个扩充文件里也存在的一样的呢?测试下,结果:是调用最后编译的分类方法。    (因为相同名字方法编译一次覆盖一次,只保留最后一个)

主题2:给NSString 类添加类方法

1.系统自带的类,有时不能满足自己的需要:比如:要求求出字符串中含有的阿拉伯数字的个数2.步骤:    1*选在分类category模板 在NSString上分    2*扩充一个类方法 +开头3.声明和实现文件
//.h#import <Foundation/Foundation.h>@interface NSString (Number)+ (int)numberCountOfString:(NSString *)str;- (int)numberCount;@end
//.m#import "NSString+Number.h"@implementation NSString (Number)+ (int)numberCountOfString:(NSString *)str{    int count=0;//局部变量要进行初始化,不然后果很严重    for (int i=0;i<[str length];i++    {        unichar c=[str characterAtIndex:i];//获取这个字符串的第i个字符        if ( c>=‘0’&&c<=‘9’)              {            count++;        }    }    return count;}@end

主题3:给NSString 类添加对象方法

#import "NSString+Number.h"@implementation NSString (Number)- (int)numberCount{int count=0;//局部变量要进行初始化,不然后果很严重    for (int i=0;i<[self length];i++//当前字符串对象的    {        unichar c=[self characterAtIndex:i];//获取第一个字符        if ( c>=‘0’&&c<=‘9’)              {            count++;        }    }    return count;} @end
技巧:可以在类方法里调用对象方法,也可以在对象方法里调用类的方法类库:很多类的集合 包含它分类的头文件 就可以使用别人写好的东西了

七、 类的深入

知识点

1.类的本质

1)实际上类也是一个对象,那么这个对象的类型是什么?是Class类型,Class里已经包含* 里;简称类对象2)利用Class 创建 Person类对象3)利用Person类对象,创建 Person类型的 对象 Person *p=[Person new];4)获取内存中的类对象:Class c=[p class]; //打印地址:%p;5)获取内存中的类对象2:Class c=[Person class];//和4)结果是一样的

2.类对象的使用

1)调用类方法 + (void)test;一般:利用类名 调用 [Person test];//类名就代表类对象现在:Class c=[p class]; [c test];//用类对象调用2)创建对象:Class c=[p class]; Person *p=[[c new] init];3)一个类在内存中只拥有一份存储空间,这个空间就叫类对象

3.类的加载和初始化

1)类的加载:在加载时,调用+ (void)load;这个类方法。由系统自动调用(当程序用没用类时,都会做这件事)://程序一启动加载类时2)利用这个特性,来监听3)当程序使用类时,又会做更深调用:+(void)initialize;4)测试,重写这些类方法打印下5)分类category里,也会具有上述特性,优先选择分类的初始化,类的初始方法不再调用;但是加载时,类和分类都会加载6)当程序启动时,就会加载项目中所有类和分类,而且加载后会调用每一个类和分类的+load方法,只会调用一次7)当第一次使用某个类时,就会调用当前类的+initialize方法8)先加载父类,再加载子类(先调用父类的+load再调用子类的+load)先加载原始类,再加载分类当有分类时,分类优先调用+initialize,类不再调用+initialize)9)想类第一次使用的时候,做些事情;这时就利用+initialize方法 //监听

代码举例

#import "Person.h"@implementation Person+ (void)test{    NSLog(@"调用了test方法");}// 当程序启动的时候,就会加载一次项目中所有的类。类加载完毕后就会调用+load方法+ (void)load{    NSLog(@"Person---load");}// 当第一次使用这个类的时候,就会调用一次+initialize方法+ (void)initialize{    NSLog(@"Person-initialize");}@end
//对应的main函数 注意把相应的头文件导入int main(){    // 利用Person这个类创建了2个Person类型的对象    Person *p = [[Person alloc] init];    Person *p2 = [[Person alloc] init];    Person *p3 = [[Person alloc] init];    // 获取内存中的类对象    Class c = [p class];    Class c2 = [p2 class];    // 获取内存中的类对象    Class c3 = [Person class];    NSLog(@"c=%p, c2=%p, c3=%p", c, c2, c3);}

八、 description方法

知识点

description方法:在NSObject.h文件里可以找到

1.一种是-开头 类的2.一种是+开头 对象的3.需求:一个类的所有属性打印出来方法1:NSLog(@“%@”,p);//打印OC对象,默认打印的时类名和对象地址;但是打印字符串,打印的却是字符串???;不能满足需求原理:首先去调用对象p的-description方法,这个方法的返回值(NSString *),NSLog让这个返回值显示在屏幕上

-description方法默认返回的时 类名+内存地址

方法2:重写description方法来覆盖父类NSObject的description
-(NSString *)description(){    return @“13333”;}//实现需求
-(NSString *)description()//由NSLog的p调用;决定实例对象的输出结果{    return [NSString stringWithFomat(@“name=%d”,_name)];}
4.+开头的description需求:拿到类对象后,想输出类对象时,打印时,会先调用类的+description方法,拿到这个的返回值,显示在屏幕上;默认返回值是类名;所以这个方法决定了类对象的输出结果5.总之重写description可以更改输出样式,注意不能在这个方法里用NSLog,否则会造成死循环

九、 NSLog

知识点

1*指针变量的地址NSLog(@“%@”,&p)和p里存储的对象地址NSLog(@“%@”,p)不是一个概念2*下划线下划线 __LINE__//输出行号;这个在文档帮助里的 Objctive-C→improved log。。。文件里可以找到3*NSLog输出C语言字符串(char= “ddd就”)时,不能有中文,否则输不出任何东西4*__func__:输出当前函数名5*__FILE__:输出源文件名6*_cmd :代表着当前方法的SEL
// 下面的代码会引发死循环- (void)test {    [self performSelector:_cmd];}

十、 SEL

一种数据类型:SEL:一个SEL数据就代表一个方法

知识点

1.方法本身是怎么存的???首先分配存储空间给这个类,类里面有个方法列表,但是这些方法是怎么存的呢?注意:每一个方法在内存中都有一个SEL的数据和它对应。方法调用:利用对象的isa找到它的类,然后去找这个方法2.程序首先会把这个test包装成SEL类型数据,通过这个数据去找到这个方法地址,最终通过这个地址找到所要调用方法,显然这个SEL数据里有方法的地址注意:有个缓存列表存储上次查询后的结果,所以先到缓存去找,找不到,再去内存去找3.怎么创建SEL数据:SEL s=@selector(方法名:);//有参数的方法 的 方法名是由冒号:的;然后可以用%d 输出4.通过SEL间接调用方法:[p perfomSelector:s] //可以传参的 WithObject(id)特别注意→_→:有参数的方法 的 方法名是由冒号:的5.打印字符串:%@6.SEL:@selector的前三个字母的大写,它就是对方法的一个包装,所以可以通过它也能找到方法7.方法都存在类对象中的9.每个方法内部都有一个SEL类型的变量:_cmd//它代表当前方法;要打印出来它的值需要先转换成字符串 NSStringFormSelector(_cmd);10.在方法里写:[self performSelector:_cmd];//会自己调用自己,陷入死循环11.SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法12.调用的方法很频繁时,可以直接把方法地址搞过来,直接去找到这个方法。高效13.说的发消息就是发一个SEL类型的数据,根据这个数据找到方法的地址找到方法。所以本质上消息就是SEL。

代码举例

#import <Foundation/Foundation.h>#import "Person.h"int main(){    Person *p = [[Person alloc] init];    [p test2];    NSString *name = @"test2";    SEL s = NSSelectorFromString(name);//把test2包装成SEL类型的数据    [p performSelector:s];//根据SEL数据找到对应的方法地址    return 0;}
0 0
原创粉丝点击