当前位置: 移动技术网 > IT编程>移动开发>IOS > iOS(闭包)block传值详解

iOS(闭包)block传值详解

2019年07月24日  | 移动技术网IT编程  | 我要评论

上犹网,风云3在线漫画,冰晶画设备

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

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

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

下面是一个简单的block

//  声明 
  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里面

- (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里面

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

next_viewcontroller.m里面

<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> 
- (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.局部变量 
 定义一个图片名字的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 里面 添加代码

//  全局变量 
//  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]; 

再添加两个方法

- (void)loaddata 
{ 
  imagenameblock_1(@"17.jpg"); 
} 
 
- (void)viewwillappear:(bool)animated 
{ 
  [self loaddata]; 
} 

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

  • ios uicollectionview实现横向滚动

    现在使用卡片效果的app很多,之前公司让实现一种卡片效果,就写了一篇关于实现卡片的文章。文章最后附有demo实现上我选择了使用uicollectionview ... [阅读全文]
  • iOS UICollectionView实现横向滑动

    本文实例为大家分享了ios uicollectionview实现横向滑动的具体代码,供大家参考,具体内容如下uicollectionview的横向滚动,目前我使... [阅读全文]
  • iOS13适配深色模式(Dark Mode)的实现

    iOS13适配深色模式(Dark Mode)的实现

    好像大概也许是一年前, mac os系统发布了深色模式外观, 看着挺刺激, 时至今日用着也还挺爽的终于, 随着iphone11等新手机的发售, ios 13系统... [阅读全文]
  • ios 使用xcode11 新建项目工程的步骤详解

    ios 使用xcode11 新建项目工程的步骤详解

    xcode11新建项目工程,新增了scenedelegate这个类,转而将原appdelegate负责的对ui生命周期的处理担子接了过来。故此可以理解为:ios... [阅读全文]
  • iOS实现转盘效果

    本文实例为大家分享了ios实现转盘效果的具体代码,供大家参考,具体内容如下demo下载地址: ios转盘效果功能:实现了常用的ios转盘效果,轮盘抽奖效果的实现... [阅读全文]
  • iOS开发实现转盘功能

    本文实例为大家分享了ios实现转盘功能的具体代码,供大家参考,具体内容如下今天给同学们讲解一下一个转盘选号的功能,直接上代码直接看viewcontroller#... [阅读全文]
  • iOS实现轮盘动态效果

    本文实例为大家分享了ios实现轮盘动态效果的具体代码,供大家参考,具体内容如下一个常用的绘图,主要用来打分之类的动画,效果如下。主要是ios的绘图和动画,本来想... [阅读全文]
  • iOS实现九宫格连线手势解锁

    本文实例为大家分享了ios实现九宫格连线手势解锁的具体代码,供大家参考,具体内容如下demo下载地址:效果图:核心代码://// clockview.m// 手... [阅读全文]
  • iOS实现卡片堆叠效果

    本文实例为大家分享了ios实现卡片堆叠效果的具体代码,供大家参考,具体内容如下如图,这就是最终效果。去年安卓5.0发布的时候,当我看到安卓全新的material... [阅读全文]
  • iOS利用余弦函数实现卡片浏览工具

    iOS利用余弦函数实现卡片浏览工具

    本文实例为大家分享了ios利用余弦函数实现卡片浏览工具的具体代码,供大家参考,具体内容如下一、实现效果通过拖拽屏幕实现卡片移动,左右两侧的卡片随着拖动变小,中间... [阅读全文]
验证码:
移动技术网