Block
//定义一个求两个数最大值函数
int maxValue (int ,int);
//函数的实现
int maxValue (int a, int b){
return a > b ? a : b;
}
//函数指针 (调用可以用 p 或者 maxValue)
int (* p)(int,int) = maxValue;
int max = p(24, 48);
block是一个匿名函数,也是一个函数,只不过没有名字而已。也叫语法块。
把函数名去掉剩余的部分就是函数类型。
对于Block 的定义:
函数的返回值类型 (^ block 变量名)(参数列表)= ^ 返回值类型(可以省略)(参数列标(形参名不可以省略)){
};
Block 的类型 :int (^)(int ,int) //就是把变量名去掉后的部分
Block 的变量名:
//定义一个无参数无返回值的 block
//无参数时,小括号不能省去
void (^ sayHi)() = ^void(){
NSLog(@"hellow");
};
sayHi();
//有参数无返回值的block
void (^ sayHi1)(int a) = ^ (int a){//block的定义
NSLog(@"%d",a);
};
sayHi1(5);//block的调用
//定义一个block 实现把数字字符串转化为整数
int (^ exchangeCagrToInt)(NSString *) = ^ int(NSString * array){
int n = [array intValue];
return n;
};
//OC对象作为参数使用
int c = exchangeCagrToInt(@"13");//如果写的是 123ABC 只会打印123 如果是 abc A 之类的就会打印出0,所以以后使用的时候要注意
NSLog(@"%d",c);
//对比C语言的函数指针
//对block 进行重命名(是给block变量类型重名名)
typedef int (^ ValueOfTwo)(int,int);
//ValueOfTwo 指向 返回值为 int 有两个 int 参数的 bloc 类型的 block
ValueOfTwo newBlock = ^(int a ,int b){//此时 newBlock 求两个数的和
return a + b;
};
//注意
int number = 20;
void (^myblock)(int ) = ^(int num){
NSLog(@"%d",num);
NSLog(@"%d",number);
//number 赋新值
//number = number - num;//这里会报错,因为在block内部不能修改局部变量的值,但是可以访问局部变量的值
};
myblock(10);
__block int number = 20;//这样让block内部可以改变我们定义的局部变量
void (^myblock)(int ) = ^(int num){
NSLog(@"%d",num);
NSLog(@"%d",number);
//number 赋新值
number = number - num;//这里不报错,因为在局部变量的值前面加上了修饰符 “__block” 注意是两个下划线哦,但是可以访问局部变量的值
};
myblock(10);
//我们称 ^ 为 托字符
1 // 2 // main.m 9 #import <Foundation/Foundation.h> 10 11 //定义一个求两个数最大值函数 12 int maxValue (int ,int); 13 //函数的实现 14 int maxValue (int a, int b){ 15 return a > b ? a : b; 16 } 17 int main(int argc, const char * argv[]) { 18 @autoreleasepool { 19 // insert code here... 20 NSLog(@"Hello, World!"); 21 //函数指针 (调用可以用 p 或者 maxValue) 22 int (* p)(int,int) = maxValue; 23 int max = p(24, 48); 24 //Block:匿名函数 也是一种函数 只不过是特殊的函数(匿名函数) 25 /* 26 对于Block 的定义: 27 函数的返回值类型 (^ block 变量名)(参数列表)= ^ 返回值类型(可以省略)(参数列标(形参名不可以省略)){ 28 }; 29 */ 30 // int (^ maxOfTwo)(int, int) = ^ int(int a,int b){ 31 // return a > b ? a :b; 32 // }; 33 int (^ maxOfTwo)(int, int) = ^ (int a,int b){ 34 return a > b ? a :b; 35 }; 36 /* 37 Block 的类型 :int (^)(int ,int) //就是把变量名去掉后的部分 38 Block 的变量名: 39 */ 40 int result = maxOfTwo (12,10); 41 NSLog(@"%d",result); 42 int (^ mutil)(int ,int) = ^int (int a,int b){ 43 return a*b; 44 }; 45 int ji = mutil(12 ,4); 46 NSLog(@"%d",ji); 47 //定义一个无参数无返回值的 block 48 //无参数时,小括号不能省去 49 void (^ sayHi)() = ^void(){ 50 NSLog(@"hellow"); 51 }; 52 sayHi(); 53 //有参数无返回值的block 54 void (^ sayHi1)(int a) = ^ (int a){ 55 NSLog(@"%d",a); 56 }; 57 sayHi1(5); 58 //block的定义 59 void (^ printNum)(int a) = ^ void (int a){ 60 NSLog(@"%d",a); 61 }; 62 //block的调用 63 printNum(10); 64 65 66 //定义一个block 实现把数字字符串转化为整数 67 int (^ exchangeCagrToInt)(NSString *) = ^ int(NSString * array){ 68 int n = [array intValue]; 69 return n; 70 }; 71 int c = exchangeCagrToInt(@"13的是否合格"); 72 NSLog(@"%d",c); 73 //对比C语言的函数指针 74 //对block 进行重命名(是给block变量类型重名名) 75 typedef int (^ ValueOfTwo)(int,int); 76 //ValueOfTwo 指向 返回值为 int 有两个 int 参数的 bloc 类型的 block 77 ValueOfTwo newBlock = ^(int a ,int b){ 78 return a + b; 79 };//此时 newBlock 求两个数的和 80 int bb = newBlock(10,12); 81 NSLog(@"%d",bb); 82 ValueOfTwo newMulBlock = ^(int a,int b){ 83 return a*b; 84 }; 85 int bc = newMulBlock(10,12); 86 NSLog(@"%d",bc); 87 88 89 //block访问外面定义的局部变量 90 __block int number = 20; 91 void (^myblock)(int ) = ^(int num){ 92 NSLog(@"%d",num); 93 NSLog(@"%d",number); 94 //number 赋新值 95 number = number - num;//这里不报错,因为在局部变量的值前面加上了修饰符 “__block” 注意是两个下划线哦,但是可以访问局部变量的值 96 97 }; 98 myblock(10); 99 } 100 return 0; 101 }
// __block 的作用就是在block 块内部使函数的局部变量不仅可以被访问,而且还可以被修改(保护局部变量可以在函数的其他地方被访问和做修改,不影响其他地方的对局部变量的操作)
//在全局的外面定义的变量就是全局变量(我们在main 函数外面声明一个)
int openValue = 12;//在函数内与函数外都可被访问
__block int number = 20;
void (^myblock)(int ) = ^(int num){
openValue ++;//全局变量不仅可以直接访问而且还可以直接被修改
NSLog(@"%d",num);
NSLog(@"%d",number);
//number 赋新值
number = number - num;//这里不报错,因为在局部变量的值前面加上了修饰符 “__block” 注意是两个下划线哦,但是可以访问局部变量的值
};
myblock(10);
1 // __block 的作用就是在block 块内部使函数的局部变量不仅可以被访问,而且还可以被修改(保护局部变量可以在函数的其他地方被访问和做修改,不影响其他地方的对局部变量的操作) 2 //练习 :把数组中的字符串拼接成一个字符串 3 // NSArray * stsArr = [NSArray arrayWithObjects:@"Hello",@"Hello",@"39", nil]; 4 NSArray * strArr = @[@"Hello",@"hhhh",@"39"]; 5 NSString * (^appendString)(NSArray *) = ^(NSArray * arr){ 6 NSString * newStr = @"";//这里不能写成:NSString * newStr = nil; 7 for (int i = 0 ; i < [arr count]; i++) { 8 NSString * append = arr[i];//获取数组中每个字符串对象 9 newStr = [newStr stringByAppendingString:append];//拼接功能,注意使用 newStr 去接受 10 } 11 return newStr; 12 }; 13 NSString * afterAppendSting = appendString(@[@"123",@"456",@"789",@"0"]); 14 NSLog(@"%@",afterAppendSting); 15 }
1 //比较两个字符串的大小 2 NSString * str1 = @"123"; 3 NSString * str2 = @"123"; 4 // BOOL (^ compareStrings)(NSString *,NSString *) = ^(NSString * str01,NSString * str02){ 5 // NSComparisonResult result = [str01 compare:str02]; 6 // return result; 7 // };//这种写法是错误的 8 9 NSComparisonResult (^ compareStrings)(NSString *,NSString *) = ^(NSString * str01,NSString * str02){ 10 NSComparisonResult result = [str01 compare:str02]; 11 return result; 12 }; 13 NSComparisonResult resu = compareStrings(str1,str2); 14 if (resu >= 1) { 15 NSLog(@"str1大于str2"); 16 } 17 if (resu == 0) { 18 NSLog(@"str1 str2相等"); 19 } 20 if (resu < 0) { 21 NSLog(@"str1小于str2"); 22 }
1 //第二节代码 2 // __block 的作用就是在block 块内部使函数的局部变量不仅可以被访问,而且还可以被修改(保护局部变量可以在函数的其他地方被访问和做修改,不影响其他地方的对局部变量的操作) 3 //练习 :把数组中的字符串拼接成一个字符串 4 // NSArray * stsArr = [NSArray arrayWithObjects:@"Hello",@"Hello",@"39", nil]; 5 NSArray * strArr = @[@"Hello",@"HH",@"39"]; 6 NSString * (^appendString)(NSArray *) = ^(NSArray * arr){ 7 NSString * newStr = @"";//这里不能写成:NSString * newStr = nil; 8 for (int i = 0 ; i < [arr count]; i++) { 9 NSString * append = arr[i];//获取数组中每个字符串对象 10 newStr = [newStr stringByAppendingString:append];//拼接功能,注意使用 newStr 去接受 11 } 12 return newStr; 13 }; 14 NSString * afterAppendSting = appendString(@[@"123",@"456",@"789",@"0"]); 15 NSLog(@"%@",afterAppendSting); 16 17 //比较两个字符串的大小 18 NSString * str1 = @"123"; 19 NSString * str2 = @"123"; 20 // BOOL (^ compareStrings)(NSString *,NSString *) = ^(NSString * str01,NSString * str02){ 21 // NSComparisonResult result = [str01 compare:str02]; 22 // return result; 23 // };//这种写法是错误的 24 25 NSComparisonResult (^ compareStrings)(NSString *,NSString *) = ^(NSString * str01,NSString * str02){ 26 NSComparisonResult result = [str01 compare:str02];//得到枚举的结果 27 //在内部判断可以不用返回值 28 if (result == NSOrderedAscending) {//升序 29 NSLog(@"str1小于str2"); 30 } 31 if (result == NSOrderedDescending) {//降序 32 NSLog(@"str1大于str2"); 33 } 34 if (result == NSOrderedSame) {//相等 35 NSLog(@"str1 str2相等"); 36 } 37 //也可以使用分支 38 switch (result) { 39 case NSOrderedAscending: 40 NSLog(@"str1小于str2"); 41 break; 42 case NSOrderedDescending: 43 NSLog(@"str1大于str2"); 44 break; 45 case NSOrderedSame: 46 NSLog(@"str1 str2相等"); 47 break; 48 default: 49 break; 50 } 51 52 return result; 53 }; 54 55 NSComparisonResult resu = compareStrings(str1,str2);//比较的方法通过返回值在外部判断 56 if (resu >= 1) { 57 NSLog(@"str1大于str2"); 58 } 59 if (resu == 0) { 60 NSLog(@"str1 str2相等"); 61 } 62 if (resu < 0) { 63 NSLog(@"str1小于str2"); 64 } 65 if (resu == NSOrderedAscending) {//升序 66 NSLog(@"str1小于str2"); 67 } 68 if (resu == NSOrderedDescending) {//降序 69 NSLog(@"str1大于str2"); 70 } 71 if (resu == NSOrderedSame) {//相等 72 NSLog(@"str1 str2相等"); 73 }
===================== =====================
说明上面 字符串比较代码1 里面错误的代码是因为
NSComparisonResult 有三个返回值(0,-1,1) 而bool只有两种情况 0 与 非0
===================== =====================
NSComparisonResult result = [str1 compare: str2]; // result 的返回值(值的形式很灵活)要 注意
result有下面三种值
NSOrderedAscending://-1等价
NSOrderedDescending://1等价
NSOrderedSame://0等价
1 // 2 // main.m 9 #import <Foundation/Foundation.h> 10 #import "Person.h" 11 #import "DownLoadManager.h" 12 #import "LoginManage.h" 13 14 int main(int argc, const char * argv[]) { 15 @autoreleasepool { 16 // insert code here... 17 NSLog(@"Hello, World!"); 18 //block练习 定义block 比较两个整数的大小 19 void (^ compareTwoNum)(int a ,int b) = ^(int a, int b){ 20 if (a > b) { 21 NSLog(@"%d 大于 %d",a,b); 22 } 23 if (a < b) { 24 NSLog(@"%d 小于 %d",a,b); 25 } 26 else{ 27 NSLog(@"%d 等于 %d",a,b); 28 } 29 }; 30 compareTwoNum(12,45); 31 //compare 是OC提供的比较的对象方法 32 //把=左边的block名字去掉就是block的类型 33 NSComparisonResult(^numCompare)(NSInteger,NSInteger) = ^(NSInteger a, NSInteger b){ 34 //数字的对象是 NSnumber 35 NSNumber * object1 = [NSNumber numberWithInteger:a]; 36 NSNumber * object2 = [NSNumber numberWithInteger:b]; 37 //笑笑语法 38 NSNumber * obj1 = @(a);//如果是数字的话 直接 @123 (@数字) 39 NSNumber * obj2 = @(b); 40 return [object1 compare:object2]; 41 }; 42 NSComparisonResult cmpResult = numCompare(45,78); 43 //NSComparisonResult 是一个枚举类型既不是指针,也不是变量 (1 对应降序) (-1 对应的升序) (0 对应的是相等) 44 //返回值类型根据需求而定 45 NSLog(@"%ld",cmpResult); 46 47 //不可变数组 48 //(将block作为方法的参数) 49 NSArray *arr = [NSArray arrayWithObjects:@"how",@"hai",@"what", nil]; 50 // NSArray * arr = @[@"hai",@"how",@"what"]; 51 //排序 记住排序的首字母是 Sort开头 52 //sortedArrayUsingSelector 默认是升序排序 返回的是一个不可变的数组 可变是不可变的子类 53 NSArray * newArr = [arr sortedArrayUsingSelector:@selector(compare:)];//相当于把原来的排好序然后拷贝一份给newArr 54 NSLog(@"%@",newArr); 55 56 57 58 //不可变数组两种排序 59 //^NSComparisonResult(id obj1, id obj2) 这个block 作为一个参数 60 /* 参数为 :^NSComparisonResult(id obj1, id obj2) { 61 return [obj1 compare:obj2]; 62 }*/ 63 //下面的方法系统默认的是升序的 64 NSArray * newArray = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 65 return [obj1 compare:obj2];//这是返回的block方法执行后的值 66 //而数组调用的sortedArrayUsingComparator方法返回一个排好序的数组 67 // return -[obj1 compare:obj2];//改变默认的排序为降序排序 68 // return [obj2 compare:obj1];//改变默认的排序为降序排序 69 }]; 70 NSLog(@"--用Block作为参数排序--%@",newArray); 71 72 73 //可变数组的排序 74 NSMutableArray * mutArr = [NSMutableArray arrayWithArray:arr]; 75 NSMutableArray * mutArr1 = [@[@"4",@"3",@"1",@"2",]mutableCopy];//把不可变的数组转变为可变数组 76 //也可以用 arrayWithArray 吧不可变数组转变为可变数组 77 //排序 (排序方法名以 sort 开头) 78 // mutArr1 sortedArrayUsingDescriptors:<#(NSArray *)#> 79 //可变数组的排序方法 80 [mutArr1 sortUsingSelector:@selector(compare:)]; 81 NSLog(@"普通方法:%@",mutArr1); 82 /*可变数组排序默认为升序 83 mutArr1 sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { 84 <#code#> 85 }*/ 86 [mutArr1 sortUsingComparator:^NSComparisonResult(id obj1, id obj2) { 87 NSLog(@"%@ %@",obj1,obj2);//打印观看内部比较规则 88 return [obj1 compare:obj2];//默认升序 89 }]; 90 NSLog(@"用block方法:%@",mutArr1); 91 92 93 94 //创建一个数组存放 5 个 person 类的对象 95 Person * per1 = [[Person alloc]initWithName:@"niujianwei" age:22 height:1.75]; 96 Person * per2 = [[Person alloc]initWithName:@"zhangjian" age:23 height:1.75]; 97 Person * per3 = [[Person alloc]initWithName:@"huangtuan" age:25 height:1.80]; 98 Person * per4 = [[Person alloc]initWithName:@"zhangping" age:18 height:1.67]; 99 Person * per5 = [[Person alloc]initWithName:@"zhanghua" age:21 height:1.70]; 100 NSArray * perArr = [NSArray arrayWithObjects:per1,per2,per3,per4,per5, nil]; 101 // NSArray * perArr2 = @[per1,per2,per3,per4,per5]; 102 // NSMutableArray * arrayPers = [@[@"per1",@"per2",@"per3",@"per4",@"per5"]mutableCopy];是错误的存放方法,因为人不要打“”,打了之后就是一个字符串了 103 // NSArray * newarr = [perArr sortedArrayUsingSelector:@selector(compare:)]; 104 // NSLog(@"对五个人排序后为%@",newarr);//这里是对象在比较不可以 105 NSArray * newPerArr = [perArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 106 // Person * per1 = obj1; 107 // Person * per2 = obj2;//转化之后直接拿 per1 与 per2 比较 108 return [[obj1 name]compare:[obj2 name]]; 109 // obj1 = (Person *)per1;//或者吧id改为 Person 110 // return [obj1 compare:obj2]; 111 }]; 112 NSLog(@"%@",newPerArr); 113 //按年龄的降序排序 114 NSArray * newByageDes = [perArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 115 return [@([obj2 age]) compare:@([obj1 age])]; 116 }]; 117 NSLog(@"按年龄的降序排序%@",newByageDes); 118 119 //按身高排序 120 NSArray * newByHeight = [perArr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 121 return -[@([obj1 height]) compare:@([obj2 height])]; 122 }]; 123 NSLog(@"按身高的降序排序%@",newByHeight); 124 125 //如果那个compare:不能满足的话,那就自己写方法 126 // NSArray * newByHeight2 = [perArr sortedArrayUsingSelector:@selector(compare:)]; 127 //block 传值 (下载:一首歌从下载的页面传过来,从一个页面吧下载的字节,下载了多少的值传过来) 128 DownLoadManager * manger = [[DownLoadManager alloc]init]; 129 [manger download:^(int n) { 130 NSLog(@"%d",n); 131 }]; 132 133 [manger chuanzhi:^(int n, int b) { 134 NSLog(@"%d %d",n,b); 135 }]; 136 137 138 LoginManage * login = [[LoginManage alloc]init]; 139 //block类型中的返回值把外部的值传到里面 140 [login loginWihtName:@"user" password:@"1234567" success:^(NSString *accountName) { 141 NSLog(@"%@",accountName); 142 } failure:^BOOL(NSString *errorMessage) { 143 NSLog(@"%@",errorMessage); 144 return 1;//把外面的值传到里面 145 }]; 146 147 } 148 return 0; 149 }
1 // 2 // Person.h 9 #import <Foundation/Foundation.h> 10 11 @interface Person : NSObject 12 { 13 NSString *_name; 14 NSInteger _age; 15 CGFloat _height; 16 } 17 //setter getter 18 - (void)setName:(NSString *)name; 19 - (NSString *)name; 20 - (void)setAge:(NSInteger)age; 21 - (NSInteger)age; 22 - (void)setHeight:(CGFloat)height; 23 - (CGFloat)height; 24 //初始化 25 - (id)initWithName:(NSString *)name 26 age:(NSInteger)age 27 height:(CGFloat)height; 28 //便利构造器 29 + (Person *)personWithNmae:(NSString *)name 30 age:(NSInteger)age 31 height:(CGFloat)height; 32 - (NSString *)description; 33 @end
1 // 2 // Person.m 9 #import "Person.h" 10 11 @implementation Person 12 //setter getter 13 - (void)setName:(NSString *)name{ 14 _name = name; 15 } 16 - (NSString *)name{ 17 return _name; 18 } 19 - (void)setAge:(NSInteger)age{ 20 _age = age; 21 } 22 - (NSInteger)age{ 23 return _age; 24 } 25 - (void)setHeight:(CGFloat)height{ 26 _height = height; 27 } 28 - (CGFloat)height{ 29 return _height; 30 } 31 //初始化 32 - (id)initWithName:(NSString *)name 33 age:(NSInteger)age 34 height:(CGFloat)height{ 35 self = [super init]; 36 if (self) { 37 _name = name; 38 _age = age; 39 _height = height; 40 } 41 return self; 42 } 43 //便利构造器 44 + (Person *)personWithNmae:(NSString *)name 45 age:(NSInteger)age 46 height:(CGFloat)height{ 47 Person * per = [[Person alloc]initWithName:name age:age height:height]; 48 return per; 49 } 50 - (NSString *)description{ 51 return [NSString stringWithFormat:@"name: %@ age: %ld height: %.2f",_name,_age,_height]; 52 } 53 @end
1 // 2 // DownLoadManager.h 9 #import <Foundation/Foundation.h> 10 11 typedef void (^myBlock)(int n); 12 typedef void (^myBlock1)(int n,int b); 13 @interface DownLoadManager : NSObject 14 { 15 16 } 17 - (void)download:(myBlock)block; 18 - (void)chuanzhi:(myBlock1)block1; 19 20 //登陆场景 21 22 @end
1 // 2 // DownLoadManager.m 9 #import "DownLoadManager.h" 10 11 12 //block类型的参数适用于回调时从里面把数据传到外面(传值的作用) 13 //把数据从一个类里面(当前这个类)传到另一个类里面(外面需要使用的地方) 14 @implementation DownLoadManager 15 16 - (void)download:(myBlock)block{ 17 //block 使用场景 18 NSLog(@"与服务器建立连接"); 19 NSLog(@"开始下载"); 20 //模拟下载字节数 21 int byte = 0; 22 for (int i = 0; i < 100; i++) { 23 byte = arc4random() % 100; 24 // NSLog(@"下载%d",byte); 25 } 26 int ddd = 100; 27 //把数据传到外部 28 NSLog(@"开始传值"); 29 block(ddd); 30 } 31 32 - (void)chuanzhi:(myBlock1)block1{ 33 int bb = 100; 34 int c = 0; 35 block1(bb,c); 36 } 37 38 //登陆 39 40 @end
1 // 2 // LoginManage.h 9 #import <Foundation/Foundation.h> 10 11 typedef void (^successfulBlock) (NSString *accountName);//对于登陆成功 12 typedef BOOL (^failureBlock)(NSString *errorMessage);//失败的情况 13 @interface LoginManage : NSObject 14 { 15 16 } 17 -(void)loginWihtName:(NSString *)name 18 password:(NSString *)password 19 success:(successfulBlock)success 20 failure:(failureBlock)failure; 21 @end
1 // 2 // LoginManage.m 9 #import "LoginManage.h" 10 11 @implementation LoginManage 12 -(void)loginWihtName:(NSString *)name 13 password:(NSString *)password 14 success:(successfulBlock)success 15 failure:(failureBlock)failure{ 16 //block类型中的返回值把外部的值传到里面 17 if ([name isEqualToString:@"user"]&& [password isEqualToString:@"123456"]) { 18 NSLog(@"登陆成功"); 19 //回调并传递信息 20 success (name);//把name 传出去 21 }else{ 22 //我们从外部得到的返回值给 result 23 BOOL result = failure(@"账户或密码错误!"); 24 if (result) { 25 NSLog(@"错误已经处理"); 26 } 27 else{ 28 NSLog(@"错误没有处理"); 29 } 30 } 31 } 32 @end
=====实战=====
1.定义一个Block,返回值为bool,有两个NSString 实现判断两个字符串是否相等。
2.创建一个数组,初始化为@“123”,@“21”,@“33”,@“69”,@“108”,@“256”使用Block,进行数组排序,并输出内容
3.定义一个Block,返回值为NSInteger ,有两个参数,一个是NSArray 一个是NSString,实现判断数组时候包含此字符串,如果包含,返回字符串下标,如果不包含返回-1.
1 // 2 // main.m 9 #import <Foundation/Foundation.h> 10 11 int main(int argc, const char * argv[]) { 12 @autoreleasepool { 13 // 1.定义一个Block,返回值为bool,有两个NSString 实现判断两个字符串是否相等。 14 // 15 // 2.创建一个数组,初始化为@“123”,@“21”,@“33”,@“69”,@“108”,@“256”使用Block,进行数组排序,并输出内容 16 // 17 // 3.定义一个Block,返回值为NSInteger ,有两个参数,一个是NSArray 一个是NSString,实现判断数组时候包含此字符串,如果包含,返回字符串下标,如果不包含返回-1. 18 printf("输入两个字符串 "); 19 char str[2][10] = {0}; 20 NSMutableArray * arrr = [NSMutableArray array]; 21 for (int i = 0; i < 2; i++) { 22 scanf("%s",str[i]); 23 arrr[i] = [[NSString alloc]initWithUTF8String:str[i]]; 24 } 25 BOOL (^isEqualTwoString)(NSString *,NSString *) = ^(NSString * str1 ,NSString *str2){ 26 return [str1 isEqualToString:str2]; 27 }; 28 int i = isEqualTwoString(arrr[0],arrr[1]); 29 if (i) { 30 NSLog(@"相等"); 31 }else{ 32 NSLog(@"不相等"); 33 } 34 35 36 //第二题 37 NSArray * arr = @[@"123",@"21",@"33",@"69",@"108",@"256"]; 38 printf("选择排序方法(1,2,3)"); 39 int chose = 0; 40 scanf("%d",&chose); 41 switch (chose) { 42 case 1: 43 { 44 NSArray * newArr = [arr sortedArrayUsingSelector:@selector(compare:)]; 45 NSLog(@"%@",newArr); 46 } 47 break; 48 case 2: 49 { 50 NSArray * newArr1 = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 51 return [obj1 compare:obj2]; 52 }]; 53 54 NSLog(@"%@",newArr1); 55 } 56 break; 57 case 3: 58 { 59 NSArray * newArr2 = [arr sortedArrayWithOptions:(NSSortOptions)1 usingComparator:^NSComparisonResult(id obj1, id obj2) { 60 return [obj1 compare:obj2]; 61 }]; 62 NSLog(@"%@",newArr2); 63 } 64 break; 65 66 default: 67 NSLog(@"输入错误"); 68 break; 69 } 70 71 72 73 74 //第三题 75 NSInteger (^ workForArrAndStr) (NSArray * ,NSString *) = ^(NSArray * arr1,NSString * str1){ 76 NSInteger i = 0; 77 for (NSString * object in arr1) { 78 i++; 79 if (object == str1) { 80 return i; 81 break; 82 } 83 } 84 NSInteger b = -1; 85 return b; 86 }; 87 NSArray * array = @[@"hello",@"HHH",@"heman",@"china",@"nanyang"]; 88 NSString * string = @"hello"; 89 NSInteger n = workForArrAndStr(array,string); 90 if (n == -1) { 91 NSLog(@"没有找到"); 92 }else{ 93 NSLog(@"所在下标为:%lu",n - 1); 94 } 95 } 96 return 0; 97 }
- (NSArray *)sortedArrayWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr
opts 为0或1 是指定排序的某个条件(是否并发和稳定)。
根据我的测试,数组里有65000个元素进行排序,
opts 为1 明显要比opts 为0 快得多。
(NSComparator)cmptr 这个就是排序
===========
1.compare在使用的时候是对OC里面对象的比较要是比较 NSinterger 的两个数字,需要转换为 NSNumber ,转化方法为:NSinterger b =100; NSNumber * bb = @(b);也可以 NSNumber * bb = @100;数字的话直接 @数字
2.NSComparisonResult 是一个枚举类型既不是指针,也不是变量 (1 对应降序) (-1 对应的升序) (0 对应的是相等)他的值只有这三个
3.block 作为参数的理解
//不可变数组两种排序
//^NSComparisonResult(id obj1, id obj2) 这个block 作为一个参数
/* 参数为 :^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2];
}*/
//下面的方法系统默认的是升序的
NSArray * newArray = [arr sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2];//这是返回的block方法执行后的值
//而数组调用的sortedArrayUsingComparator方法返回一个排好序的数组
// return -[obj1 compare:obj2];//改变默认的排序为降序排序(注意前面加了一个 -号,默认为升序加一个 负号就是降序)
// return [obj2 compare:obj1];//改变默认的排序为降序排序
}];
NSLog(@"--用Block作为参数排序--%@",newArray);
4.在有compare比较后的函数的返回值 可用 NSComparisonResult
5.注意在创建好Person的对象之后在添加到数组的时候,不要忘了,添加的是person对象,不能写成字符串
(错误例子:NSMutableArray * arrayPers = [@[@"per1",@"per2",@"per3",@"per4",@"per5"]mutableCopy];)
6.Block使用的时候可以当做参数,(注意与函数的回调相联系)
1 一、概述 2 Block是C级别的语法和运行时特性。Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存、堆内存的引用,我们甚至可以将一个Block作为参数传给其他的函数或者Block。 3 4 二、热身 5 先看一个比较简单的Block例子: 6 7 int multiplier = 7; 8 int (^myBlock)(int) = ^(int num) { 9 return num * multiplier; 10 }; 11 在这个例子中,myBlock是一个Block变量,它接受一个int类型的参数,返回一个int类型的值。是不是很像C函数? 12 13 来,让我们typedef一下 14 15 typedef void (^BoolBlock)(BOOL);//一个只接受一个BOOL参数,没有返回值的block 16 typedef int (^IntBlock)(void);//一个没有参数,返回int的block 17 typedef BoolBlock (^HugeBlock)(IntBlock);//看看,这个HugeBlock的参数和返回值都是block 18 三、更详细的例子 19 注意:上面的typedef都还有效~ 20 21 主动调用一下: 22 23 - (void)someMethod 24 { 25 BoolBlock ablock = ^(BOOL bValue) { 26 NSLog(@"Bool block!"); 27 }; 28 ablock(); 29 } 30 作为参数返回: 31 32 typedef void (^BoolBlock)(BOOL); 33 - (BoolBlock)foo() 34 { 35 BoolBlock ablock = ^(BOOL bValue) { 36 NSLog(@"Bool block!"); 37 }; 38 return [[ablock copy] autorelease];//一定要copy,将其复制到堆上,更详细的原理,将在后续章节讲解 39 } 40 类的一个成员: 41 42 @interface OBJ1 : NSObject 43 @property (nonatomic, copy)BoolBlock block;//理由同上啊,同学们 44 @end 45 46 OBJ1 *obj1 = ... 47 obj1.block = ^(BOOL bValue) { 48 NSLog(@"Bool block!"); 49 }; 50 其他函数的参数: 51 52 - (void)foo(BoolBlock block) 53 { 54 if (block) { 55 block(); 56 } 57 } 58 甚至其他block的参数: 59 60 BoolBlock bBlock = ^(BOOL bV){if(Bv){/*do some thing*/}}; 61 HugeBlock hBlock = ^(BoolBlock bB) {bB();}; 62 63 hBolck(bBlock); 64 啊,全局变量!: 65 66 static int(^maxIntBlock)(int, int) = ^(int a, int b){return a>b?a:b;}; 67 int main() 68 { 69 printf("%d ", maxIntBlock(2,10)); 70 return 0; 71 } 72 好了,你知道block大概能怎么用了。 73 74 四,特殊的标记,__block 75 如果要在block内修改block外声明的栈变量,那么一定要对该变量加__block标记: 76 77 int main() 78 { 79 __block int i = 1024; 80 BoolBlock bBlock = ^(BOOL bV) { 81 if (bV) { 82 i++;//如果没有__block标记,是无法通过编译的。 83 } 84 }; 85 }