美文网首页
关于block的理解

关于block的理解

作者: 请叫我魔法师 | 来源:发表于2017-07-25 13:26 被阅读0次

FBI WARNING:纯属个人见解,有可能是错误的理解。O(∩_∩)O
block作用
1.可以传递数据,取代代理模式很方法,代码简洁。
2.当做回调,这是主要的用途。
写法也简单,固定格式,照着写就行,一般不会出错,记得防止出现循环引用就行。别的没啥。

问题:block它是怎么传递数据的,回调怎么工作的。我冥思苦想一番,感觉有点眉目了,记录一下,怕忘了。

一、函数。(或者叫<方法>,叫法不一样,感觉没啥区别)
1.1正常情况下,定义一个函数包括名字,参数,返回值3部分。
1.2使用起来包括定义、实现、调用3步。
例如:
定义+实现。大括号里就是一个函数的实现部分,前面定义了名字和参数返回值

- (void)testFunction1WithParameter:(NSString *)title{
   
    NSLog(@"方法1的实现 -- %@", title);
}

调用:

[self testFunction1WithParameter:@"方法1"];

这就是函数的使用。

二、block
block是特殊函数!!!
这点很重要。时时刻刻记得这一点。重点:block是函数。
再强调一下,block就是特殊函数,本质还是函数,既然是函数,函数怎么用,block也怎么用,和上面函数是一样。
苹果用^这个符号标记block,告诉人们看到这个符号,就是个block了。没别的意思,给这个函数加了个标记,写法不一样了。
1.block也有方法名,参数,返回值。和普通函数一样。
定义一个block:和普通函数一样,都是定义+实现

    void(^block)() = ^(){
        NSLog(@"block的实现");
    };

这就定义了一个无参数无返回值,叫block名字的的函数,用^标记一下,大括号依然是函数的实现部分。

 block();

执行函数,由于block是特殊的函数,执行方式和普通函数也不一样,不用self调用,直接写函数名字跟个小括号就行了。比较不像oc。
总结:block是特殊函数,特殊的地方就在于定义和调用方式和普通函数不一样,实现部分没变化,还是在大括号里面实现。

另外:如果定义一个字符串,NSstring *a = @"字符串";
NSstring 是类型,a是名字。
函数有没有类型?当然有!
block这种函数的写法,相当于用这个特殊符号标记了一个函数的类型。void(block)() 这段代码就是block的定义。有名字、参数类型、返回值类型。
所以,block的写法可以定义一个函数的类型。这个函数的类型就是void(^)(),名字就是block。

2.经过上面的洗脑,慢慢接受了block是函数的观点,和普通函数没啥区别。就是样子怪怪的罢了。
如果block像上面这么定义+实现+调用,用法其实和普通函数没啥区别,就体现不出它的价值了。

注:如果block不作为参数,需要在^符号后面直接写上block名字,然后直接调用,如第1的例子。
如果作为参数需要像普通的参数那样写,在最后写上block名字,如下。

//block传递数据
- (void)testFunction2WithParameter:(NSString *)title testBlock:(void(^)(NSString *msg))block{
    NSLog(@"方法2的实现 -- %@", title);
    block(@"block的调用--传递数据data");
}

block参数的类型就是括号里的一串。这样就把一个函数(用block的写法)作为参数传给另外一个参数了。

3.回调
理解了函数的定义、实现、调用,函数作为参数传递给另外一个函数,就该说回调了。
重点:当A函数作为B函数的参数,那么A函数就具有了回调的功能。由于函数作为参数必须写成block格式,所以一般说block具有回调的功能。
上面说了,函数的使用包括定义、实现、调用3步。一般定义和实现写一块。
调用写在需要调用的地方。也就是说函数的调用和实现是分开的。
比如第一部分介绍普通函数的部分,定义实现完了,调用的时候才走实现的部分,这点很重要。
函数A:(即block)
void(^)(NSString *msg)
把A函数作为另外一个函数的参数,如下:
函数B:
//B的定义和实现

- (void)testFunction2WithParameter:(NSString *)title testBlock:(void(^)(NSString *msg))block{
    NSLog(@"方法2的实现 -- %@", title);
    block(@"block的调用--传递数据data");
}

函数B的调用

    [self testFunction2WithParameter:@"方法2" testBlock:^(NSString *msg) {
        NSLog(@"block的实现");
        NSLog(@"方法2的调用 -- %@", msg);
    }];

后面的大括号其实是A函数的实现部分,这种block的写法,其实把函数的定义、实现、调用都分开了。而一般函数定义和实现是写一块的,比如B函数。
但是实现和调用都是分开的,这点没变。都是通过调用函数去实现大括号{ }里面的代码。

通过观察:可以得到:
1.B函数的实现里面写了block的调用,
2.B函数的调用的时候,把block实现了。
会出现什么情况?

按代码的执行顺序
第一步、在viewDidLoad里调用B函数,这是需要跳到B函数的实现部分,即大括号里
第二步、在B函数的实现里面,发现了A函数block的调用
第三步、既然有调用,必须去寻找怎么实现的,就跳到了A函数的实现部分
第四步、发现A的实现部分在B函数的调用后面,所以代码又回到了B函数的调用部分,回到了第一步的代码部分viewDidLoad里。这就实现了回调。

C41BE5D5-C24D-49BD-843C-CB3B71BCC1C9.png

如果block带有参数,就把这个参数回调了B函数的执行地方,可以传递数据,这就实现了传递数据的功能。例如上面的函数传了个字符串。比如一些网络请求方法,通过写一个block就能把请求的数据传递到这个请求方法调用的地方,就算是得到了数据。

swift闭包一个道理,捋一捋就通了。

相关文章

  • 关于block的理解

    FBI WARNING:纯属个人见解,有可能是错误的理解。O(∩_∩)Oblock作用1.可以传递数据,取代代理模...

  • 关于block的理解

    block的类型详解 关于block的知识,在网络上的资料那是相当的多。不过这里还是想来谈谈自己对block的理解...

  • 关于Block的理解

    Block是将函数及其执行上下文封装起来的对象。在开发过程中我们经常会用到Block处理一些事物,下面我们就对Bl...

  • 九、Block之(一)Block内部结构及调用本质

    一、Block内部数据结构 1.调用分析 2.关于block调用中 block->FunPrt()的理解 bloc...

  • 关于 __ block 再理解

    关于 __ block 再理解 我们都知道:block不准修改外部变量的值,这里所说的外部变量的值,指的是栈中指针...

  • 关于IOS的Block的理解

    IOS中的Block大致分为三种 第一种 堆block 我们知道 程序在内存中 堆是程序员分配的和使用的栈是系统使...

  • iOS 关于block前缀的理解

    关于block:修饰符 用copy(要从堆区 拷贝到栈区) 前缀修饰符: __block:默认情况下,bloc...

  • Block原理探究(上篇)-Block本质及存储域问题

    主要内容:1.理解Block的本质2.理解Block的存储域分类3.理解Block的Copy原理 一、探究Bloc...

  • Block

    将我认为的比较易懂的关于block的文章整理到一起: 文章链接: 你真的理解__block修饰符的原理么? __b...

  • iOS面试之Block大全

    Block Block内容如下: 关于Block 截获变量 __block修饰符 Block的内存管理 Block...

网友评论

      本文标题:关于block的理解

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