IOS开发-block分析

作者: 没阳光的午后 | 来源:发表于2015-12-15 14:01 被阅读2164次

block的定义

// 无参无返回
void(^block)();
// 无参有返回
int(^block1)();
// 有参有返回
int(^block1)(int number);

也可以直接打入inline来自动生成block格式

<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
        <#statements#>
    };

block的循环引用

  • 如果要在block中直接使用外部强指针会发生错误,使用以下代码在block外部实现可以解决
__weak typeof(self) weakSelf = self;
  • 但是如果在block内部使用延时操作还使用弱指针的话会取不到该弱指针,需要在block内部再将弱指针强引用一下
__strong typeof(self) strongSelf = weakSelf;

block的内存管理

  • 无论当前环境是ARC还是MRC,只要block没有访问外部变量,block始终在全局区
  • MRC情况下
    1.block如果访问外部变量,block在栈里
    2.不能对block使用retain,否则不能保存在堆里
    3.只有使用copy,才能放到堆里
  • ARC情况下
    1.block如果访问外部变量,block在堆里
    2.block可以使用copy和strong,并且block是一个对象

通过block来传值

  • 在控制器间传值可以使用代理或者block,使用block相对来说简洁

在前一个控制器的touchesBegan:方法内实现如下代码


    ModalViewController *modalVc = [[ModalViewController alloc] init];
    
    modalVc.valueBlcok = ^(NSString *str){
        
        NSLog(@"ViewController拿到%@",str);
    };
    
    [self presentViewController:modalVc animated:YES completion:nil];

**在ModalViewController控制器的.h文件中声明一个block属性 **@property (nonatomic ,strong) void(^valueBlcok)(NSString *str);

并在.m文件中实现方法


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 传值:调用block
    if (_valueBlcok) {
        _valueBlcok(@"123");
    }
}

这样在ModalViewController回到上一个控制器的时候,上一个控制器的label就能显示ModalViewController传过来的字符串

block作为一个参数使用

新建一个类,在.h文件中声明一个方法- (void)calculator:(int(^)(int result))block;

并在.m文件中实现该方法

- (void)calculator:(int (^)(int))block
{
    self.result = block(self.result);
}

在其他类中调用该方法

    CalculatorManager *mgr = [[CalculatorManager alloc] init];
    [mgr calculator:^(int result){
        result += 5;
        return result;
    }];

block作为返回值使用

masonry框架中我们可以看到如下用法make.top.equalTo(superview.mas_top).with.offset(padding.top); 这个方法实现就是将block作为返回值来使用

来分析一下这段代码
其实可以将这段代码看成make.top,make.equalTo,make.with,make.offset,所以可以得出一个结论是make.top返回了一个make,才能实现make.top.equalTo

**那来模仿一下这种功能的实现** 新建一个类,在.h文件中声明一个方法- (CalculatorManager *(^)(int a))add;```

.m文件中实现方法

- (CalculatorManager * (^)(int a))add
{
    return ^(int a){
        _result += a;
        return self;
    };
}

这样就可以在别的类中实现上面代码的用法

mgr.add(1).add(2).add(3);

block的变量传递

  • 如果block访问的外部变量是局部变量,那么就是值传递,外界改了,不会影响里面
  • 如果block访问的外部变量是__block或者static修饰,或者是全局变量,那么就是指针传递,block里面的值和外界同一个变量,外界改变,里面也会改变

验证一下是不是这样
通过Clang来将main.m文件编译为C++
在终端输入如下命令clang -rewrite-objc main.m

void(*block)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));
void(*block)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a));

可以看到在编译后的代码最后可以发现被__block修饰过得变量使用的是&a,而局部变量是a

还在学习中,有错误请指出,谢谢!!

相关文章

  • iOS开发-由浅至深学习block

    iOS开发-由浅至深学习block iOS开发-由浅至深学习block

  • IOS开发-block分析

    block的定义 也可以直接打入inline来自动生成block格式 block的循环引用 如果要在block中直...

  • Objc Block实现分析

    Objc Block实现分析 Block在iOS开发中使用的频率是很高的,使用的场景包括接口异步数据的回调(AFN...

  • iOS开发基础:开发两年的你也不会写的Block

    iOS开发基础:开发两年的你也不会写的Block iOS开发基础:开发两年的你也不会写的Block

  • iOS 开发 Block 原理分析

    前言 无论在面试还是在工作中,总会碰到 block 是什么?block 循环引用怎么办?block 修饰符使用什么...

  • CDUnknownBlockType获取参数的方法

    CDUnknownBlockType 在iOS开发过程中大家都会使用block,可在逆向开发的时候block就显得...

  • oc Block

    标签:ios开发入门 对Block的经典认识 Block一点也不神秘

  • block 实用小例子

    本篇是简单介绍iOS 开发中block的使用(附demo): /* 声明一个block (返回类型)(^block...

  • iOS开发 (解惑-02)

    一、block 1)iOS开发的内存分配;2)block的变量捕获机制:为了保证在block的内部可以正常访问外部...

  • Block

    Block Block定义以及表达式 在iOS开发中针对于Objective-C我们经常提到Block,对于Swi...

网友评论

本文标题:IOS开发-block分析

本文链接:https://www.haomeiwen.com/subject/qkpuhttx.html