http://www.sufeinet.com/plugin.php?id=keke_group

苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

查看: 3425|回复: 5

[语法] iOS中Block的理解和用法

[复制链接]
发表于 2018-12-16 13:10:48 | 显示全部楼层 |阅读模式
本帖最后由 竹林风 于 2018-12-15 17:30 编辑

介绍

我们可以把Block当做Object-C的匿名函数。Block允许开发者在两个对象之间将任意的语句当做数据进行传输,这要比引用定义在别处的函数更直观。
Block具有封闭性,又能够很容易获取上下文的相关状态信息。
Block是代码块,其本质和变量类似。不同的是代码块存储的数据是一个函数体。使用Block,就可以像其他标准函数一样,传入参数,并得到返回值。

1.Block的格式:
[Objective-C] 纯文本查看 复制代码
int (^myBlock)(int ,int) = ^(int num1, int num2) {       
 return num1 + num2;   
 };
NSLog(@"%d",myBlock(5,4)); 

打印结果为:9

  • int: 为Block的返回值类型,可以为空 void
  • myBlock: Block对象名称,可以理解为变量名
  • ^:块的语法标记,声明为一个Block对象
  • num1:第一个参数,类型为int
  • num2:第二个参数,类型为int
  • {}: Block代码块的主题部分


2.定义和使用

a.定义无返回值、无参数的Block
[Objective-C] 纯文本查看 复制代码
// 1.定义无返回值、无参的Block
    void (^block1)() = ^() {
        NSLog(@"无返回无参的Block");
    };

b.定义无返回值、有参数的Block
[Objective-C] 纯文本查看 复制代码
// 2.定义无返回值、有参数的Block
    void (^block2)(int) = ^(int a) {
        NSLog(@"%d",a);
    };

c.定义返回值为OC对象的Block
[Objective-C] 纯文本查看 复制代码
// 3.定义返回值为OC对象的Block
    NSString *(^block3)(NSString *) = ^(NSString *string) {
        string = [NSString stringWithFormat:@"%@_%@",string,string];
        return string;
    };

定义Block变量就相当于定义了一个函数,只有在调用block的时候才会执行其主体块{}里面的代码
3.__block关键字的使用
在Block的代码块里面,是不能修改在外面定义的变量,并且在给block赋值的时候,已经对代码块里的变量做了值的拷贝(只读不可修改)。
[Objective-C] 纯文本查看 复制代码
int x = 5;
    int (^block4)(int) = ^(int y) {
        int z = x + y;
        return z;
    };
    NSLog(@"%d,%d",x +=5,block4(5));
打印的值是10,10
  • 分析:变量x在Block外定义的,在Block代码块编译的时候,取的x的值为之前的5(不可修改)。因此即使执行x += 5的使x的值变为10,但Block代码块里的x依然是5,所以block(5)的值为5+5=10。


接下来在变量前添加__block关键字修饰后,些变量在block代码块里的就是可更改的(可读可写),执行代码时取变量最新的值。


[Objective-C] 纯文本查看 复制代码
__block int x = 5;
    int (^block4)(int) = ^(int y) {
        int z = x + y;
        return z;
    };
    NSLog(@"%d,%d",x +=5,block4(5));

打印的值就是10,15


4.作为OC对象的属性,实现对象之间的传值

实现一个小例子,在FirstVC里面定义一个按钮,跳转到第二个页面。在SecondVC里面添加两个按钮,一个直接返回,一个是传递一个颜色的值,再返回,并同时修改第一个页面的背景颜色。


FirstVC.m


[Objective-C] 纯文本查看 复制代码
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor yellowColor];
    self.title = @"苏飞论坛";
    
    UIButton *btnAdd = [[UIButton alloc]initWithFrame:CGRectMake(80, 100, 200, 40)];
    [btnAdd setTitle:@"查看Allison" forState:UIControlStateNormal];
    [btnAdd setBackgroundColor:[UIColor orangeColor]];
    [btnAdd addTarget:self action:@selector(btnAddAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnAdd];
    
//    UIButton *btnEdit = [[UIButton alloc]initWithFrame:CGRectMake(80, CGRectGetMaxY(btnAdd.frame) + 20, 200, 40)];
//    [btnEdit setTitle:@"修改第一个会员信息" forState:UIControlStateNormal];
//    [btnEdit setBackgroundColor:[UIColor orangeColor]];
//    [btnEdit addTarget:self action:@selector(btnEditAction) forControlEvents:UIControlEventTouchUpInside];
//    [self.view addSubview:btnEdit];
    
    
    
}

-(void)btnAddAction{
    SecondVC *second = [SecondVC new];
    second.colorBlock = ^(UIColor *color) {
        self.view.backgroundColor = color;
    };
    [self.navigationController pushViewController:second animated:YES];
}


SecondVC.h

[Objective-C] 纯文本查看 复制代码
#import <UIKit/UIKit.h>

@interface SecondVC : UIViewController

// 第一步定义, Block作为property属性
/*
 void: Block的返回值为空,即无返回值;
 colorBlock: Block的作为对象属性时的属性名;
 (UIColor *color): Block的参数是UIColor实例对象
 */
@property (nonatomic, copy) void(^colorBlock)(UIColor *color);

@end


SecondVC.m

[Objective-C] 纯文本查看 复制代码
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"会员Allison";
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *btnAdd = [[UIButton alloc]initWithFrame:CGRectMake(80, 100, 200, 40)];
    [btnAdd setTitle:@"直接返回" forState:UIControlStateNormal];
    [btnAdd setBackgroundColor:[UIColor orangeColor]];
    [btnAdd addTarget:self action:@selector(btnBackAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnAdd];
    
    UIButton *btnEdit = [[UIButton alloc]initWithFrame:CGRectMake(80, CGRectGetMaxY(btnAdd.frame) + 20, 200, 40)];
    [btnEdit setTitle:@"返回并修改背景颜色" forState:UIControlStateNormal];
    [btnEdit setBackgroundColor:[UIColor orangeColor]];
    [btnEdit addTarget:self action:@selector(btnChangeAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btnEdit];
}

-(void)btnBackAction{
    [self.navigationController popViewControllerAnimated:YES];
}

-(void)btnChangeAction{
    // 随机生成的颜色
    UIColor *color = [UIColor colorWithRed:arc4random()%256/255.0 green:arc4random()%256/255.0 blue:arc4random()%256/255.0 alpha:1];
    _colorBlock(color);
    [self.navigationController popViewControllerAnimated:YES];
}


看效果:

7.gif

附件: Test-Block.zip (214.17 KB, 下载次数: 0)


1. 开通SVIP会员,免费下载本站所有源码,不限次数据,不限时间
2. 加官方QQ群,加官方微信群获取更多资源和帮助
3. 找站长苏飞做网站、商城、CRM、小程序、App、爬虫相关、项目外包等点这里
发表于 2018-12-16 16:55:38 | 显示全部楼层
真是难得给力的帖子啊。
发表于 2018-12-16 16:57:36 | 显示全部楼层
强烈支持楼主ing……
发表于 2018-12-16 23:05:19 | 显示全部楼层
我只是路过打酱油的。
发表于 2018-12-17 10:13:06 | 显示全部楼层
无回帖,不论坛,这才是人道。
发表于 2018-12-18 11:34:18 | 显示全部楼层
我是路过 去 去中午饭的
您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2024-11-8 13:51

© 2014-2021

快速回复 返回顶部 返回列表