iOS开展block说明
浅谈block使用方法
对于block他用着确实方便,好多人都非常迷茫,这里写了一个Demo解说block的使用方法
好多人都觉得block是用于后一个界面向前一个界面传值用的,事实上更详细的说是经常使用来界面之间的传值,事实上仅仅要须要传值不管是view之间还是controller之间还是view与controller之间都能够用block,当传值比較少时用block比使用代理更方便.
block创建后都在栈区存放的,block的语义特性必须用copy,通过copy能够将block从栈区放到堆区,保证每次使用block时block都存在,因此我们使用时经常要定义属性,使用属性是为了保存该block变量
例如以下举个样例解说
首先在project中创建两个类BlockViewController和BlockView
在BlockView中仅仅是为了创建几个button,在BlockViewController中使用,能够降低BlockViewController的代码任务量,可是BlockView中仅仅有一个实例变量button是,而且在延展中定义的,外部无法訪问到,当我们为button加入点击触发事件就须要获得button的tag值,这时就要把所点击button的tag获取到,来为不同的button加入响应事件
在BlockView.h中定义一个block变量和一个方法,方法的參数是block类型的
#import <UIKit/UIKit.h> //第一步:声明block typedef void(^ButtonActionBlock)(NSInteger tag); @interface BlockView : UIView -(void)buttonActionBlock:(ButtonActionBlock)didClickButton; @end
在BlockView.m中
<pre name="code" class="objc">#import "BlockView.h" @interface BlockView () //Block //block创建后都在栈区存放的,block的语义特性必须用copy,通过copy能够将block从栈区放到堆区,保证每次使用block时block都存在 @property (nonatomic, copy) ButtonActionBlock buttonActionBlock; @property (nonatomic, strong) UIButton *button; @end @implementation BlockView - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { CGFloat x = 5; CGFloat y = 5; CGFloat width = 65; CGFloat height = 40; //创建button for (int i = 0; i < 4; i ++) { self.button = [UIButton buttonWithType:(UIButtonTypeSystem)]; self.button.frame = CGRectMake(x + i * (width + 10), y, width, height); self.button.tag = 100 + i; self.button.backgroundColor = [UIColor cyanColor]; self.button.layer.cornerRadius = 5; self.button.layer.masksToBounds = YES; [self.button setTitle:[NSString stringWithFormat:@"%d",i] forState:UIControlStateNormal]; [self.button addTarget:self action:@selector(handleButton:) forControlEvents:UIControlEventTouchUpInside]; [self addSubview:_button]; } } return self; } //处理button的点击事件,将tag值传给block的參数回调block -(void)handleButton:(UIButton *)button { NSLog(@"3"); NSInteger tag = button.tag; //第二步,回掉block self.buttonActionBlock(tag),NSLog(@"6"); NSLog(@"7"); } //该方法中self.buttonActionBlock = didClickButton;运行后会调用属性buttonActionBlock的setter方法,将block变量didClickButton传给setter方法的參数 -(void)buttonActionBlock:(ButtonActionBlock)didClickButton { NSLog(@"1"); NSLog(@"-----------didClickButton = %p",didClickButton); self.buttonActionBlock = didClickButton; } //重写属性buttonActionBlock的setter方法,在此重写setter方法目的是为了表明该方法是把传进来的block变量进行深拷贝,复制到了堆区,并赋给了实例变量buttonActionBlock,使我们在不论什么时候都能使用block变量(block的创建后在栈区,出了方法就被回收,无法再使用) - (void)setButtonActionBlock:(ButtonActionBlock)buttonActionBlock { NSLog(@"2"); if (_buttonActionBlock != buttonActionBlock) { NSLog(@"++++++++buttonActionBlock = %p",buttonActionBlock); _buttonActionBlock = [buttonActionBlock copy]; } } @end
BlockViewController.m文件里导入BlockView.h文件
BlockViewController.m文件中代码实现
#import "BlockViewController.h" #import "BlockView.h" // 获取RGB颜色 #define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a] @interface BlockViewController ()<UIScrollViewDelegate> @property (nonatomic, strong) UIImageView *YJFImageView; @end @implementation BlockViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { } return self; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = RGBA(252, 230, 201, 1.0); BlockView *blockView = [[BlockView alloc] initWithFrame:CGRectMake(10, 0, 320 - 20, 50)]; blockView.backgroundColor = [UIColor lightGrayColor]; [self.view addSubview:blockView]; //BlockView的对象blockView调用其方法buttonActionBlock: //第三步。调用block [blockView buttonActionBlock:^(NSInteger tag) { //block的实现 NSLog(@"4"); [self handleButton:tag]; NSLog(@"5"); }]; [self createView]; } //处理自己定义toolBar的点击事件 -(void)handleButton:(NSInteger)tag { switch (tag) { //...button case 100: { self.YJFImageView.image = LOADIMAGE(@"2", @"jpg"); } break; //...button case 101: { self.YJFImageView.image = LOADIMAGE(@"5", @"jpg"); } break; //...button case 102: { self.YJFImageView.image = LOADIMAGE(@"6", @"jpg"); } break; //...button case 103: { self.YJFImageView.image = LOADIMAGE(@"4", @"jpg"); } break; default: break; } } -(void)createView { self.YJFImageView = [[UIImageView alloc] initWithFrame:CGRectMake(10, 52, 320 - 20, 568 - 64 - 75)]; self.YJFImageView.image = LOADIMAGE(@"8", @"jpg"); self.YJFImageView.userInteractionEnabled = YES; [self.view addSubview:_YJFImageView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
通过程序执行控制台输出结果例如以下:
点击button前:
由此结合代码实现中打的log能够看出
<pre name="code" class="objc">didClickButton和传入属性的setter方法的參数是一个地址,则
,BlockView.m文件里
<pre name="code" class="objc">buttonActionBlock:方法中把didClickButton拷贝了一份到栈区,赋值给实例变量_buttonActionBlock
点击button后:
结合代码实现中打的log能够看出整个Block的运行过程,也能够通过打断的查看Block的运行过程
版权声明:本文博主原创文章。博客,未经同意不得转载。
相关文章
- iOS开发-常用第三方开源框架介绍(你了解的ios只是冰山一角)
- IOS 30多个iOS常用动画,带详细注释
- iOS开发之微信支付
- IOS和安卓ui设计常用尺寸及基本知识
- iOS之UI--使用SWRevealViewController实现侧边菜单功能详解实例
- iOS之UI--主流框架的搭建--仿制QQ的UI框架
- iOS开发UI篇—IOS开发中Xcode的一些使用技巧
- iOS开发UI篇—ios应用数据存储方式(归档)
- iOS开发UI篇—ios应用数据存储方式(偏好设置)
- iOS中 蓝牙2.0详解/ios蓝牙设备详解
- C++问题:if( input.rdstate() & std::ios::failbit )
- iOS Human Interface Guidelines 用户界面(交互)指南 UI苹果官网介绍
- iOS Info.plist
- Swift学习笔记(3)iOS 9 中的网络请求
- iOS音视频开发十三:视频渲染,用 Metal 渲染
- Unity3d代码从Android/IOS迁移到WindowsPhone经验笔记
- iOS Socket编程
- ios 仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.
- 【iOS开展-50】使用它来创建一个新的类的实现代码包,因此,不自觉地练习简单MVC实验,附带动画
- Mac环境配置 - iOS开发人员 -待续
- 华为:鸿蒙OS不是安卓和iOS的拷贝;胡润世界500强榜发布:苹果第一,腾讯第六