服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - IOS - iOS(闭包)block传值详解

iOS(闭包)block传值详解

2021-04-21 19:31iOS开发网 IOS

这篇文章主要介绍了iOS(闭包)block传值的相关知识以及代码分享,对此有兴趣的朋友可以学习下。

iOSAPP开发的过程中 我们会用到很多需要传值的地方 传值的方式也多种多样 有:代理传值、通知传值、KVC、KVO、block、单例 等。其中block 因为其简洁实用规范的代码 无疑是大牛们传值的不二选择 但对于初学者来说要理解并能运用 起初确实有些难以理解 以下我将细细的介绍下block

首先我总结了一下block的公式:

  1. 步骤1.block 的声明 返回值类型(^block 的名字)(参数列表);
  2. 步骤2.block 实现 block的名字 = ^(参数列表)(){};
  3. 步骤3.block 的调用 block的名字();

下面是一个简单的block

?
1
2
3
4
5
6
7
8
9
10
//  声明
  void(^blockName)(int num,NSString *string);
//  实现
  blockName = ^(int num,NSString *string)
  {
    NSLog(@"%d,%@",num,string);
  };
//  调用
  blockName(520,@"phyone_");
}

由该例可以看出block的代码执行顺序和其他的代码执行顺序不一样 它是先执行声明代码 然后执行调用代码 最后才执行实现代码 由此我们利用block的回调性质 达到我们传值效果 当然这只是在一个页面的一段代码 只是说明了它具有传值的作用 下面我们来试试 多页面之间的block反向传值 由于是反向传值 所以我们创建两个ViewController (ViewController,Next_ViewController)先由ViewController跳到Next_ViewController里将里面的值反向传给ViewController
以下是代码

ViewController.m里面

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor purpleColor];
 UILabel *lable = [[UILabel alloc]initWithFrame:CGRectMake(100, 200, 200, 100)];
  lable.backgroundColor = [UIColor brownColor];
  [self.view addSubview:lable];
   
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap)];
  [self.view addGestureRecognizer:tap];
}
- (void)tap
{
  Next_ViewController *NVC = [[Next_ViewController alloc]init];
  NVC.block = ^(NSString *content){
    NSLog(@"%@",content);
    UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(100, 200, 100, 100)];
    [button setTitle:content forState:UIControlStateNormal];
    button.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:button];
  };
  [self presentViewController:NVC animated:YES completion:nil];
}

Next_ViewController.h里面

?
1
2
//block 是分配在栈里面的用copy
@property(nonatomic,copy) void(^block)(NSString *content);

Next_ViewController.m里面

?
1
2
3
4
<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"><span style="font-size:12px;">{</span></p>
<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"><span style="font-size:12px;"void(^imageNameBlock_1)(NSString *imageName);</span></p>
<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"><span style="font-size:12px;"void(^lableBlock)(NSString *tontentText);</span></p>
<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"><span style="font-size:12px;">}</span></p>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor orangeColor];
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.frame = CGRectMake(100, 200, 100, 50);
  [button setTitle:@"123456" forState:UIControlStateNormal];
  button.backgroundColor = [UIColor redColor];
  [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:button];
}
- (void)buttonAction:(UIButton *)sender
{
//  点击按钮 返回上一个页面 同时通过block 把这个值传到上一个页面
  self.block(sender.titleLabel.text);
  [self dismissViewControllerAnimated:nil completion:nil];
}

另外:block 还有两个问题

1.怎么改变block里面的值

用上面的代码 在ViewController.m viewDidLoad 里面 添加代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1.局部变量
 定义一个图片名字的Block
 */
//  局部变量
   
  void(^imageNameBlock)(NSString *imageName);
//  如果想修改Block里面的值 需添加__block修饰
   
//  __block UIImage *image;
  imageNameBlock = ^(NSString *imageName)
  {
    image = [UIImage imageNamed:imageName];
    self.view.backgroundColor = [UIColor colorWithPatternImage:image];
  };
  imageNameBlock(@"17.jpg");

就会出现 Use of undeclared identifier 'image' 错误情况 原因是我们试图改变block里面的值 解决办法就是 添加 __block 修饰(解注释

__block UIImage *image;) 就行了

2.block的循环引用

用上面的代码 在ViewController.m viewDidLoad 里面 添加代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//  全局变量
//  block循环 引用 解决 我们用弱引用 __block
  __weak ViewController *VC = self;
   
  __block UIImage *image = nil;
  imageNameBlock_1 = ^(NSString *imageName)
  {
    image = [UIImage imageNamed:imageName];
    VC.view.backgroundColor = [UIColor colorWithPatternImage:image];
  };
  UILabel *lable = [[UILabel alloc]initWithFrame:CGRectMake(100, 200, 200, 100)];
  lable.backgroundColor = [UIColor brownColor];
  [self.view addSubview:lable];
   
  UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap)];
  [self.view addGestureRecognizer:tap];

再添加两个方法

?
1
2
3
4
5
6
7
8
9
- (void)loadData
{
  imageNameBlock_1(@"17.jpg");
}
 
- (void)viewWillAppear:(BOOL)animated
{
  [self loadData];
}

当出现循环引用是我们用__weak修饰下 但具体机制还不太懂 希望高人指点,感谢大家对服务器之家的支持。

延伸 · 阅读

精彩推荐
  • IOSiOS常见的几个修饰词深入讲解

    iOS常见的几个修饰词深入讲解

    这篇文章主要给大家介绍了关于iOS常见的几个修饰词的相关资料,iOS修饰词包括assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite,文中通过示...

    郡王丶千夜7422021-05-10
  • IOSxcode8提交ipa失败无法构建版本问题的解决方案

    xcode8提交ipa失败无法构建版本问题的解决方案

    xcode升级到xcode8后发现构建不了新的版本。怎么解决呢?下面小编给大家带来了xcode8提交ipa失败无法构建版本问题的解决方案,非常不错,一起看看吧...

    Cinna丶7542021-02-03
  • IOSiOS APP实现微信H5支付示例总结

    iOS APP实现微信H5支付示例总结

    这篇文章主要介绍了iOS APP实现微信H5支付示例总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下...

    一张小A11332021-06-01
  • IOSiOS中时间与时间戳的相互转化实例代码

    iOS中时间与时间戳的相互转化实例代码

    这篇文章主要介绍了iOS中时间与时间戳的相互转化实例代码,非常具有实用价值,需要的朋友可以参考下。...

    张无忌!4812021-03-09
  • IOSiOS10 Xcode8适配7个常见问题汇总

    iOS10 Xcode8适配7个常见问题汇总

    这篇文章主要为大家详细汇总了iOS10 Xcode8适配7个常见问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    索马里猫10332021-02-01
  • IOS谈一谈iOS单例模式

    谈一谈iOS单例模式

    这篇文章主要和大家谈一谈iOS中的单例模式,单例模式是一种常用的软件设计模式,想要深入了解iOS单例模式的朋友可以参考一下...

    彭盛凇11872021-01-19
  • IOSiOS逆向教程之logify跟踪方法的调用

    iOS逆向教程之logify跟踪方法的调用

    这篇文章主要给大家介绍了关于iOS逆向教程之logify跟踪方法调用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学...

    Mr.Guo11472021-04-28
  • IOSIOS网络请求之AFNetWorking 3.x 使用详情

    IOS网络请求之AFNetWorking 3.x 使用详情

    本篇文章主要介绍了IOS网络请求之AFNetWorking 3.x 使用详情,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    总李写代码6892021-03-04