OC语言 - block:定义 | 用作参数
block | 函数
1 - 相同点
① 都可以保存代码
② 参数、返回值均可有可无
③ 调用方式一样
block 本质上是匿名函数,同样也是 OC对象。在 iOS 4.0 之后的类都添加了 block 支持
如何使用 block
1 - 定义一个 block
1 // 标准格式 2 int (^maxBlock)(int a, int b) = ^int (int x,int y){ 3 4 return x > y ? x : y; 5 }; 6 7 int maxNumber = maxBlock(32,55); 8 NSLog(@"%d",maxNumber); 9 10 11 // 右边返回值类型可省略;左边可省略参数 12 int (^block02)(int) = ^(int x){ 13 14 return x*x; 15 }; 16 int result02 = block02(9); 17 NSLog(@"%d",result02); 18 19 20 // 无参无返回值 21 void(^block03)(void) = ^void(){ 22 NSLog(@"The block03!"); 23 }; 24 block03(); 25 // 无参时:左边参数括号是不能省略的;右边返回类型、参数括号均可省略 26 void(^block04)(void) = ^{ 27 NSLog(@"Fuck the block04!"); 28 }; 29 block04();
2 - block 同函数指针十分相似
// 定义一个函数
int maxValue (int a , int b){ return a > b ? a : b; }
// 函数指针
int maxNumber = maxValue(18,59); // 函数指针 int (*p)(int,int) = maxValue; int result = p(10,15);
3 - 开发中往往使用 typedef 关键字用来简化代码
1 #import <Foundation/Foundation.h> 2 3 // typedef 可以大大简化 block 声明,写出通俗易懂的代码 4 typedef int (^myBlock)(int,int); 5 int main(int argc, const char * argv[]) { 6 @autoreleasepool { 7 8 // 方式一 9 myBlock block01; 10 block01 = ^(int a,int b){ 11 12 return a+b; 13 }; 14 NSLog(@"%d",block01(123,3));// 调用 15 16 17 // 方式二 18 myBlock block02 = ^(int num1,int num2){ 19 20 return num1*num2; 21 }; 22 NSLog(@"%d",block02(123,3));// 调用 23 } 24 return 0; 25 }
4 - 下面我们手写几个 block,熟悉其使用方式
① 处理字符串
1 // 分割字符串 2 NSString *(^blockSeg)(NSString *str01,NSString *str02) = ^NSString*(NSString *st01,NSString *st02){ 3 4 return [[st01 componentsSeparatedByString:st02] firstObject]; 5 }; 6 NSString *strSub = blockSeg(@"I love my honey W , forever !",@","); 7 NSLog(@"%@",strSub);// I love my honey W
1 // 拼接字符串 2 NSArray *array01 = [NSArray arrayWithObjects:@"美女",@"喜欢",@"野兽", nil]; 3 // 方式一 4 NSString *(^appendingStringBlock01)(NSArray *) = ^(NSArray * array){ 5 NSMutableString *str = [NSMutableString stringWithCapacity:1]; 6 for (NSString *string in array) { 7 [str appendString:string]; 8 } 9 return [NSString stringWithString:str]; 10 }; 11 NSLog(@"%@",appendingStringBlock01(array01)); 12 13 // 方式二 14 NSString *(^appendingStringBlock02)(NSArray *) = ^(NSArray * array){ 15 NSString *str = @""; 16 for (NSString *string in array) { 17 str = [str stringByAppendingString:string]; 18 } 19 return str; 20 }; 21 NSLog(@"%@",appendingStringBlock02(array01)); 22 23 // 方式三 24 NSString *(^appendingStringBlock03)(NSArray *) = ^(NSArray *array){ 25 NSString *str = @""; 26 for (NSString *string in array) { 27 str = [NSString stringWithFormat:@"%@%@",str,string]; 28 } 29 return str; 30 }; 31 NSLog(@"%@",appendingStringBlock03(array01));
② block 排序
// - Person.h
1 #import <Foundation/Foundation.h> 2 @interface Person : NSObject 3 4 @property(nonatomic,copy)NSString *name; 5 @property(nonatomic,copy)NSString *sex; 6 @property(nonatomic,assign)NSInteger age; 7 - (id)initWithName:(NSString *)name 8 sex:(NSString *)sex 9 age:(NSInteger )age; 10 11 @end
// - Person.m
1 #import "Person.h" 2 @implementation Person 3 4 - (id)initWithName:(NSString *)name 5 sex:(NSString *)sex 6 age:(NSInteger )age{ 7 self = [super init]; 8 if (self) { 9 _name = name; 10 _sex = sex; 11 _age = age; 12 } 13 return self; 14 } 15 16 - (NSString *)description{ 17 return [NSString stringWithFormat:@"%@,%@,%ld",_name,_sex,_age]; 18 } 19 20 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 4 int main(int argc, const char * argv[]) { 5 6 Person *person1 = [[Person alloc] initWithName:@"刘大" sex:@"男" age:11]; 7 Person *person2 = [[Person alloc] initWithName:@"陈二" sex:@"女" age:13]; 8 Person *person3 = [[Person alloc] initWithName:@"张三" sex:@"男" age:15]; 9 Person *person4 = [[Person alloc] initWithName:@"李四" sex:@"男" age:32]; 10 Person *person5 = [[Person alloc] initWithName:@"王五" sex:@"女" age:28]; 11 12 NSArray *array = [NSArray arrayWithObjects:person1,person2,person3,person4,person5, nil]; 13 // 年龄升序 14 NSArray *newArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 15 Person *per1 = (Person*)obj1; 16 Person *per2 = (Person*)obj2; 17 18 19 if (per1.age > per2.age) { 20 return NSOrderedDescending; 21 } 22 if (per1.age < per2.age) { 23 return NSOrderedAscending; 24 }else{ 25 26 return NSOrderedSame; 27 } 28 }]; 29 NSLog(@"%@",newArray); 30 31 32 // 名字排序 33 NSArray *array05 = [NSArray arrayWithObjects:@"Jeson",@"Hazell",@"Solina",@"Cacy",@"Lee", nil]; 34 NSArray *newArray05 = [array05 sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 35 return [obj1 compare:obj2]; // 升序 36 // return [obj2 compare:obj1];// 降序 37 }]; 38 NSLog(@"%@",newArray05); 39 40 return YES; 41 }
③ 使用 block 模拟迅雷下载(注意值的传向问题)
// - XunLeiDownload.h:
1 #import <Foundation/Foundation.h> 2 typedef void (^tetsBlock)(int n); 3 4 @interface XunLeiDownload : NSObject 5 6 -(void)beginDownload:(tetsBlock)block; 7 8 @end
// - XunLeiDownload.m
1 #import "XunLeiDownload.h" 2 3 @implementation XunLeiDownload 4 // 谁要传值,谁就把 block 用作参数 5 -(void)beginDownload:(tetsBlock)block{ 6 7 for (int i = 0; i < 10; i ++) { 8 int kb = arc4random() % 100; 9 block(kb);// block 作为参数时是从内部向外传值:在外部,谁调用就传给谁 10 } 11 } 12 13 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "XunLeiDownload.h" 3 4 int main(int argc, const char * argv[]) { 5 6 XunLeiDownload *xml = [[XunLeiDownload alloc] init]; 7 // 外部调用 block 8 [xml beginDownload:^(int n) { 9 NSLog(@"下载了%d个资源",n); // n 就是从 block 内部传出的 kb 10 }]; 11 12 return YES; 13 }
④ 使用 block 模拟登录页面:block 用作参数传值且有返回值时(注意返回值的传向)
// - LoginManager.h
1 #import <Foundation/Foundation.h> 2 typedef void (^SuccessfulBlock)(NSString*infoBack); 3 typedef BOOL (^FailBlock) (NSString *errorManager); 4 5 @interface LoginManager : NSObject 6 7 - (void)loginWithUserName:(NSString *)name 8 password:(NSString *)password 9 successfulBlock:(SuccessfulBlock)successBlock 10 failBlock:(FailBlock)failBlock; 11 12 @end
// - LoginManager.m
1 #import "LoginManager.h" 2 @implementation LoginManager 3 4 -(void)loginWithUserName:(NSString *)name password:(NSString *)password successfulBlock:(SuccessfulBlock)successBlock failBlock:(FailBlock)failBlock{ 5 6 7 if ([name isEqualToString:@"123"] && [password isEqualToString:@"12345"]) { 8 successBlock([NSString stringWithFormat:@"Hazell,请来小黑屋面谈"]);// 由内向外传值 9 }else{ 10 11 12 NSString *warning = [NSString stringWithFormat:@"警告!%@是非法人员",name]; 13 int result = failBlock(warning); 14 15 // block 的返回值是从外向内返回的,block 内部拿到值后继续往下编程 16 if (result) { 17 NSLog(@"密码是:%@",password); 18 }else{ 19 NSLog(@"%@",[NSString stringWithFormat:@"%@代号已被销毁",name]); 20 } 21 } 22 } 23 24 @end
// - main.m
1 #import <Foundation/Foundation.h> 2 #import "LoginManager.h" 3 4 int main(int argc, const char * argv[]) { 5 6 LoginManager *manager = [[LoginManager alloc] init]; 7 // name=123 password=12345 8 [manager loginWithUserName:@"123" password:@"1234" successfulBlock:^(NSString *infoBack) { 9 10 NSLog(@"%@",infoBack);// infoBack 从 block 内部传出至此,在该代码块中使用 11 } failBlock:^BOOL(NSString *errorManager) { 12 13 NSLog(@"%@",errorManager);// errorManager 同 infoBack 14 return arc4random()%2 ; // 返回结果再次传回 block 内部 15 }]; 16 17 return YES; 18 }
分类:
OC语言
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)