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

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

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

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

,BlockView.m文件里

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

点击button后:

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

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

时间: 2024-10-11 22:27:17

iOS开展block说明的相关文章

iOS中block类型大全

iOS中block类型大全 typedef的block 作为属性的block 作为变量的block 作为方法变量入参的block 作为方法参数的block 无名block 内联函数的block 递归调用的block 作为方法返回值的block 作为函数名的block(太过奇葩,完全不知道怎么用-_-!) iOS中block类型大全,码迷,mamicode.com

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

ios中block的用法和函数的用法大致相同 但是block的用法的灵活性更高: 不带参数的block: void ^(MyBlock)() = ^{}; 调用的时候  MyBlock(); 带参数的block: int ^(MyBlock)(int,int) = ^(int a,int b){return a+b;} 调用MyBlock(5,6); 将block当作某个类的属性的写法 typedef void (^BlockOption)(); @property (nonatomic,ass

IOS中Block的循环引用

@interface DemoObj() @property (nonatomic, strong) NSOperationQueue *queue; @end @implementation DemoObj - (instancetype)init { self = [super init]; if (self) { self.queue = [[NSOperationQueue alloc] init]; } return self; } - (void)dealloc { NSLog(@"

iOS 中Block以及Blocks的使用

一.ios中block的使用 Block可以帮助我们组织独立的代码段,并提高复用性和可读性.iOS4在UIKit中引入了该特征.超过100个的Apple API都使用了Block,所以这是一个我们必须开始熟悉的知识. Block是什么样的? 你可以使用^操作符来声明一个Block变量,它表示一个Block的开始. int num1 = 7; int(^aBlock)(int) = ^(int num2) { return num1+nunm2; }; 在如上代码中我们将Block声明为一个变量,

iOS中Block介绍(一)基础

ios开发block的使用指南,以及深入理解block的内存管理,也适用于osx开发.讨论范围:block的使用,内存管理,内部实现.不包含的内容:gc arc下的block内存,block在c++中的使用. AD: 一.概述 Block是C级别的语法和运行时特性.Block比较类似C函数,但是Block比之C函数,其灵活性体现在栈内存.堆内存的引用,我们甚至可以将一个Block作为参数传给其他的函数或者Block. 二.热身 先看一个比较简单的Block例子: int multiplier =

iOS中block用法之两个界面传值问题

Block的使用有很多方面,其中传值只是它的一小部分,但是很常用更实用,下面介绍Block在两个界面之间的传值用法: 先说一下思想: 首先,创建两个视图控制器,在第一个视图控制器中创建一个Label和一个Button,其中Label是为了显示第二个视图控制器传过来的字符串, Button是为了push到第二个界面. 第二个界面的只创建一个TextField,是为了输入文字,当输入文字并且返回第一个界面的时候(第二个视图将要消失的时候),就将这个 TextFiled中的文字传给第一个界面并且显示在

IOS中block的使用方法

X.1 初探Block 在这一小节我们先用一些简单范例来导入block的概念. X.1.1 宣告和使用Block 我们使用「^」运算子来宣告一个block变数,而且在block的定义最后面要加上「;」来表示一个完整的述句(也就是将整个block定义视为前面章节所介绍的简单述句,因为整个定义必须是一个完整的句子,所以必须在最后面加上分号),下面是一个block的范例: 1: int multiplier = 7 ; 2: int (^myBlock)( int ) = ^( int num) 3:

iOS之block浅谈

前言 ios4.0系统已开始支持block,在编程过程中,block被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行.block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.它和传统的函数指针很类似,但是有区别:block是inline的,并且它对局部变量是只读的. block和函数的相似性:(1)可以保存代码(2)有返回值(3)有形参(4)调用方式一样. block的使用 1.block的定义 // 声明和实现写在一起,就像变量的声明实现 int a

iOS: 定义 Block

定义 typedef void (^RFAudioBasicBlock) (void); typedef void (^RFAudioSuccessBlock) (BOOL flag); typedef void (^RFAudioSuccessDetailBlock) (BOOL flag, NSURL *url, NSTimeInterval duration); typedef void(^RFAudioSuccessURLBlock) (BOOL flag, NSURL *url); 作

IOS中 Block简介与用法(一)

?Block简介: Block的实际行为和Function很像,最大的差别是在可以存取同一个Scope的变量值.Block实体形式如下: ^(传入参数列){行为主体}; Block实体开头是"^",接着是由小括号所包起来的参数列(比如 int a, int b, int c),行为主体由大括号包起来,专有名字叫做block literal.行为主体可以用return回传值,类型会被compiler自动辨别.如果没有参数列要写成: ^(void). 例如下面的一个例子: [cpp] vi