美文网首页
block 的使用 (一)

block 的使用 (一)

作者: 自律改变现状 | 来源:发表于2018-08-20 17:18 被阅读0次

iOS 三大回调方式:目标动作回调,委托回调,代码块回调,喜欢 block 是因为他很简洁紧凑,代码可读性高。

block 格式


block 简单操作

无返回值无参数

void(^block)(void) = ^{
    NSLog(@"Hello, World!");
};
        
block(); // 调用方式

无返回值有参数

void(^block)(int) = ^(int value){
    NSLog(@"小狗%d个月大了",value);
};
block(6);

Block[22835:1629584] 小狗6个月大了

无返回值多参数

void(^block)(NSString *,int) = ^(NSString *name, int number){
    NSLog(@"%@已经%d个月大了",name,number);
};
block(@"猫猫",3);

Block[22902:1635602] 猫猫已经3个月大了

有返回值多参数

NSString *(^block)(NSString *,int) = ^(NSString *name, int number){
    return [NSString stringWithFormat:@"%@已经%d个月大了",name,number];
};
NSLog(@"%@",block(@"猫猫",3));

Block[22933:1639591] 猫猫已经3个月大了
block 还有一个功能,捕获变量的能力。
int b = 6;
        
void(^add)(int) = ^(int a){
    NSLog(@"%d",a + b);
};
add(10);

Block[23038:1657584] 16
但是在示例当中代码块里面只能获取,不能改变 b 的值,不然会报错。

想要在代码块里面改变值,只需要在 声明变量前加一个前缀 __block ,就可以了。

__block int b = 6;
        
void(^add)(int) = ^(int a){
    b = b + a;
};  
add(10);
NSLog(@"b = %d",b);

Block[23165:1673618] b = 16

原因:在未加前缀之前,block 传递的是 b 的值,添加前缀后而是把 b 的地址传过去了,所以在block内部便可以修改到外面的变量了。

还可以用 typedef 声明 block。
#import <Foundation/Foundation.h>

typedef void(^Block)(NSString *text);

@interface Person : NSObject

@property (nonatomic, copy) Block block;

@property (nonatomic, copy) NSString *name;

- (void)callYouBack;

@end

#import "Person.h"

@implementation Person

- (void)callYouBack {
    // 判断是否初始化了 block, 不然会奔溃
    if (self.block) {
        self.block(@"回电话");
    }
}

- (void)dealloc {
    NSLog(@"释放%@",self);
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {

        Person *p = [[Person alloc] init];
        // 初始化 block
        p.block = ^(NSString *text) {
            NSLog(@"text = %@",text);
        };
        [p callYouBack];
        
    }
    return 0;
}

Block[23476:1713267] text = 回电话
Block[23606:1724744] 释放<Person: 0x10043c1e0>

有个需求需要在代码块里面,给 p 类中的 name 赋值。

Person *p = [[Person alloc] init];
// 初始化 block
p.block = ^(NSString *text) {
    NSLog(@"text = %@",text);
    p.name = @"张三";
};
 [p callYouBack];

Block[23476:1713267] text = 回电话

程序执行完,发现一个问题! p 类没有释放掉内存。
这里面是因为循环引用了,p 持有了 block,而 block 又持有了 p。所以才释放不了。
解决方式: weak 弱引用

Person *p = [[Person alloc] init];
// 创建 block
__weak typeof(p) weakP = p;
p.block = ^(NSString *text) {
    NSLog(@"text = %@",text);
    weakP.name = @"张三";
};
[p callYouBack];

Block[23606:1724744] text = 回电话
Block[23606:1724744] 释放<Person: 0x10043c1e0>

https://www.zhihu.com/question/30779258

相关文章

  • ios block使用

    iOS Block的使用一 .最简单的block使用******使用block的三个步骤:1.定义block变量 ...

  • iOS Block -浅析 文章

    Block 的使用有两种:1.独立Block 。2.内联Block 。 《一》独立Block 使用方式 一、定义一...

  • 白话block

    本文内容 什么是block? block的用途 block的用法 block在使用中遇到的问题 如何使用xcode...

  • iOS Block使用注意

    block本质是两个结构体,使用block使代码简单易读。使用Block注意: 1、block内部使用外部指针,会...

  • block使用及其底层原理

    一 block基本使用 二 block底层结构 三 block变量捕获 四 block的类型 五 block对象类...

  • OC中的block回顾

    1.block声明 2.block的typedef 2.1 typedef的使用 2.2 声明block类型的使用...

  • iOS Block的使用

    一 .最简单的block使用 使用block的三个步骤: 1.定义block变量2.创建block代码块3.调用b...

  • Block其实很简单

    Block的几种情况 block的使用 1.使用block实现反向传值 2.利用block写响应式编程的技巧

  • iOS通知使用总结

    NSNotification 一、添加通知 1.使用selector添加 2.使用block添加 使用block添...

  • block:block的循环引用

    一、block的循环引用二、使用__weak、__unsafe_unretained、__block解决block...

网友评论

      本文标题:block 的使用 (一)

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