源代码下载

浅谈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前:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveWpmMTIzNTQ2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

由此结合代码实现中打的log能够看出

<pre name="code" class="objc">didClickButton和传入属性的setter方法的參数是一个地址,则


,BlockView.m文件里

<pre name="code" class="objc">buttonActionBlock:方法中把didClickButton拷贝了一份到栈区,赋值给实例变量_buttonActionBlock

点击button后:

结合代码实现中打的log能够看出整个Block的运行过程,也能够通过打断的查看Block的运行过程

版权声明:本文博主原创文章。博客,未经同意不得转载。

iOS开展block说明的更多相关文章

  1. iOS中block的用法 以及和函数用法的区别

    ios中block的用法和函数的用法大致相同 但是block的用法的灵活性更高: 不带参数的block: void ^(MyBlock)() = ^{}; 调用的时候  MyBlock(); 带参数的 ...

  2. iOS开发--Block

    iOS开发--Block 1.什么是Block,block 的作用 ui开发和网络常见功能实现回调,按钮的事件处理方法是回调方法以及网络下载后的回调处理 (1)按钮 target-action   一 ...

  3. iOS之block

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

  4. iOS开发——Block详解

    iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...

  5. ios开发 block语句块

    ios开发 block语句块 1.block 理解为匿名函数 2.block变量的定义 //定义block变量,^表示定义block //技巧:函数名左右加括号,在函数名前面在加^ void (^bl ...

  6. iOS中Block介绍(一)基础

    ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...

  7. iOS中Block介绍 基础

    ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中 ...

  8. iOS 中Block以及Blocks的使用,闭包方法调用

    OC: -(void)dataWithUrl:(NSString*)string AndId:(NSInteger)id returnName:(void(^)(NSString*name))back ...

  9. iOS中block类型大全

    iOS中block类型大全 typedef的block 作为属性的block 作为变量的block 作为方法变量入参的block 作为方法参数的block 无名block 内联函数的block 递归调 ...

  10. IOS中block和代理

    从ios4开始引入block,就是代码块,结构类c语言 基本结构 返回值 (^block名称)(参数):int(^BlockName)(int):返回值为int型,参数是一个int值的叫BlockNa ...

随机推荐

  1. 编程算法 - 远征队(expedition) 代码(C)

    远征队(expedition) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 题目: 远征队有一辆卡车须要行驶L单位的距离, 開始时, 车上有P单位的 ...

  2. (六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版)

    原文:(六)RabbitMQ消息队列-消息任务分发与消息ACK确认机制(PHP版) 在前面一章介绍了在PHP中如何使用RabbitMQ,至此入门的的部分就完成了,我们内心中一定还有很多疑问:如果多个消 ...

  3. [Angular] Subscribing to router events

    In our root component, one thing we can do is subscribe to Router events, and do something related t ...

  4. Android 5.0中使用JobScheduler

    在这篇文章中,你会学习到在Android 5.0中怎样使用JobScheduler API. JobScheduler API同意开发人员在符合某些条件时创建运行在后台的任务. 介绍 在Android ...

  5. 基于 MySQL 5.6 keepalived的双主搭建

    环境介绍: 说明 IP 节点1 192.168.56.56 节点2 192.168.56.57 w_ip 192.168.56.6 安装keepalived tar -zxvf keepalived- ...

  6. want cry -- 137,139,445

    通过wireshark抓包发现smb的请求报文,目的端口为445,没有应答报文 之前设置了“阻止连接”导致smb访问被拒绝.修改为要求对连接进行加密 就可以访问

  7. 【39.29%】【codeforces 552E】Vanya and Brackets

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  8. HBase总结(十一)hbase Java API 介绍及使用演示样例

    几个相关类与HBase数据模型之间的相应关系 java类 HBase数据模型 HBaseAdmin 数据库(DataBase) HBaseConfiguration HTable 表(Table) H ...

  9. 【t004】切割矩阵

    Time Limit: 1 second Memory Limit: 50 MB [问题描述] 给你一个矩阵,其边长均为整数.你想把矩阵切割成总数最少的正方形,其边长也为整数.切割工作由一台切割机器完 ...

  10. 10 个免费的 C/C++ 集成开发环境

    集成开发环境(IDE)可以给程序员提供很大的帮助.大多数的IDE包含编译器和解释器.例如微软的 Visual Studio 本身内置的编译器和解释就是很好的例子,Eclipse 是另一个很好的例子.鼓 ...