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 }
复制代码

 

posted on   低头捡石頭  阅读(404)  评论(0编辑  收藏  举报

编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示