------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
扩充数据类型
1.SEL(方法地址)
SEL:类中的方法包装成的数据,运行时候会存在与缓存中。
SEL在Object-C中定义:
typedef struct objc_selector *SEL;
①SEL属于运行时机制
②类中的每个方法(对象方法及类方法)都对应一个SEL数据
③调用方法时,将方法名包装成一个SEL数据,然后进入类中查找SEL(方法地址),调用方法
④每个SEL对应一个方法地址。
⑤带参数的方法,用selector包装方法时,方法名后面要有一个冒号“:”。
⑥每个方法内部都有个隐藏的SEL数据_cmd,_cmd代表当前方法,是系统自带的。
实例示范:
main.m文件
#import <Foundation/Foundation.h> #import "Student.h" int main() { Student *stu = [[Student alloc]init]; SEL sel_test = NSSelectorFromString(@"test");//将字符test转换为SEL数据 //以下通过SEL数据调用方法,说明每个方法有一个对应的SEL数据(方法地址) [stu performSelector:sel_test];//通过SEL数据调用test方法 //将方法名为test1:封装成SEL数据,通过SEL数据调用test1方法 [stu performSelector:@selector(test1:) withObject:@"Hua_san"]; [Student test]; return 0; }
Student.h文件
#import <Foundation/Foundation.h> @interface Student : NSObject + (void) test; - (void) test; - (void) test1:(NSString *)str; @end
Student.m文件
#import "Student.h" @implementation Student +(void)test { SEL sel = _cmd;//每个方法中都有一个隐藏的SEL数据_cmd,_cmd代表着当前方法 NSString *str_sel = NSStringFromSelector(sel);//将sel转换为NSString数据类型 NSLog(@"test类方法中_cmd代表的方法名:%@",str_sel); } -(void)test { NSLog(@"This is test"); } -(void)test1:(NSString *)str { NSLog(@"This is test1----参数:%@",str); } @end
结果输出:
2015-04-25 09:01:24.363 05-数据类型相互转换[624:26953] This is test 2015-04-25 09:01:24.364 05-数据类型相互转换[624:26953] This is test1----参数:Hua_san 2015-04-25 09:01:24.364 05-数据类型相互转换[624:26953] 查看了类方法test中_cmd代表的方法名:test
2.Block(代码块)
*什么是Block?
Block 是iOS在4.0之后新增的程式语法,是用来封装一段代码,任何时候都可以执行。其有点类似函数,与函数不同的是:Block可以在运行时动态保存一段代码,函数必须是编译前写好,使用block使程序运行高效,所以苹果官方特别推荐使用。
*Block与函数
相同点:
①可以保存一段代码,随时调用
②可以有参数与返回值
③调用方式相同
不同点:
①函数只能保存静态代码,编译前要写好,而block可以保存动态代码,其要保存代码可以是程序运行时动态产生的。
②定义block时,如果block没有形参时候,后面的小括号可以省略
③block可以访问局部变量,不可以修改局部变量,函数可以访问与修改局部变量
实例示范:
函数举例:
#import <Foundation/Foundation.h> typedef int (*Number)(int,int);//声明一个返回值为int类型,有两个int参数的指针,名字为Number int Max(int a,int b) { return a>b?a:b; } int Min(int a,int b) { return a<b?a:b; } int main() { int a = 10,b = 20; Number max = Max;//用max指针指向Max函数 Number min = Min;//用min指针指向Min函数 NSLog(@"max(%d,%d) = %d",a,b,max(10,20)); NSLog(@"min(%d,%d) = %d",a,b,min(a,b)); return 0; }
block举例:
#import <Foundation/Foundation.h> typedef int (^Number)(int,int);//声明一个返回值为int类型,有两个int参数的block,名字为Number int main() { int a = 10,b = 20; Number max = ^(int a,int b){return a>b?a:b;};//定义一个max的block Number min = ^(int a,int b) {return a<b?a:b; }; //定义一个min的block NSLog(@"max(%d,%d) = %d",a,b,max(10,20)); NSLog(@"min(%d,%d) = %d",a,b,min(a,b)); return 0; }
结果输出:
2015-04-25 09:56:44.011 06-Block[754:43626] max(10,20) = 20 2015-04-25 09:56:44.013 06-Block[754:43626] min(10,20) = 10
课堂笔记
1.SEL
① 方法的存储位置
? 每个类的方法列表都存储在类对象中
? 每个方法都有一个与之对应的SEL类型的对象
? 根据一个SEL对象就可以找到方法的地址,进而调用方法
? SEL类型的定义
typedef
struct
objc_selector *SEL;
②SEL对象的创建
SEL s =
@selector(test);
SEL s2 = NSSelectorFromString(@"test");
③SEL对象的其他用法
// 将SEL对象转为NSString对象
NSString*str =
NSStringFromSelector(@selector(test));
Person *p= [Person
new];
//调用对象p的test方法
[p performSelector:@selector(test)];
2.Block
lBlock封装了一段代码,可以在任何时候执行
lBlock可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。
l苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多
//定义一个min的block
int (^min) (int ,int) = ^(int a,int
b) { return a<b?a:b; };
//调用一个block,与函数调用一致
min(10,20);
Block可以访问局部变量,但是不能修改。
intsum=10;
int(^MyBlock)(int)= ^(intnum){
sum++;//编译报错
returnnum* sum;
};
如果要修改就要加关键字:__block
__block intsum
= 10;