Block的详细使用(五)

Block 的初步理解

  1. 例如定义一个block:void(^myblock)(int);=>与int a;比较
  2. block的类型:void(^)(int);=>等价于int
  3. block的变量名:myblock=>等价于a
  4. 注意:
    1. 定义block时若有输入参数(本例为int),参数名可有(int x)可无(int)但必须有参数的类型,但实现是必须有参数的类型和变量名.
    2. 实现block时,也可以将block返回类型写在实现中(通常不写),写在仅仅挨着^后面,不需要(),这样有利于让实现者知道该block返回什么值,(其实这样写更加规范,苹果官方有使用:当带有返回值的block作为一个方法的参数时,当调用这个方法时,系统的提示代码在block实现中会加上返回类型,具体看典例)
 //实现中写返回参数类型
    NSString *(^myblockx)(int) = ^NSString *(int a){
        return @"";
    };
    //实现中不写返回参数类型
    NSString *(^myblockx2)(int) = ^(int a){
        return @"";
    };

定义一个block

  1. 无返回值有参数

     //定义一个block变量,然后给这个变量赋值:myblock
    //此时void(^)(int)为类型名,myblock1为变量名
    //int a ; a = 3;
    void(^myblock1)(int);
    myblock1 = ^(int a){
    };
    //定义一个block变量并赋值//int a = 3;
    void(^myblock2)(int) = ^(int a){
    };
    
  2. 无返回值无参数

      //1.先定义,在赋值
    void(^myblock0)();
    myblock0 = ^{
    };
    //2.定义时赋值(略)
    
  3. 有返回值无参数

     //1.先定义,在赋值(略)
    //2.定义时赋值
    int(^myblock4)()=^{
        return 3;
    };
    
  4. 有返回值有参数且参数(注意参数中可以有变量名也可以没有变量名,变量名与实现时参数的变量名无关联)

     //1.先定义,在赋值
    int(^myblock7)(int c ,int d);
    myblock7 = ^(int a, int b){
        return a + b;
    };
    //2.定义时赋值
    int(^myblock6)(int ,int) = ^(int a, int b){
        return a + b;
    };
    
    
  5. 参数为block

    //重要:block的传入参数为block类,理解!!!!
    //1.定义时赋值(参数block无变量名)
    //同理当传入参数为block时,可以有变量名,也可以无变量名
    //传入的block类型为void(^)():无返回值无参数型
    int(^blockx)(void(^)())= ^(void(^x)()){
        return 2;
    };
    //2.先定义,在赋值(参数block有变量名:mmm,参数block中的参数名q也是可有可无)
    //传入的block类型为int(^)(int):有返回值有参数型
    int(^blocky)(int(^mmm)(int q));
    blocky = ^(int(^x)(int a)){
        return 2;
    };
    

使用typedef定义block类

  1. 面向对象思想:将block定义成一个自定义类,然后使用这个类创建变量赋值block,使用typedef
//定义一个sumblock类(参数中的变量名可有可无)
    typedef int(^sumblock)(int c ,int d);
    sumblock block = ^(int a,int b){
        return a + b;
    };
    //实质:
    // sumblock block;等价于 int(^block)(int,int);
    //用block替换掉sumblock;
    
    //举例:定义一个blockz,传入参数为sumblock类,然后赋值
    //sumblock只是类型,变量名可有可无,也可以传入sumblock vvv
    int(^blockz)(sumblock);
    blockz = ^(sumblock block2){
        return 2;
    };

Block的常见使用

  1. block成为属性
    1. 举例:

      @property (nonatomic, strong) void(^operation)();
      @property (nonatomic, strong) NSString *operation;
      
    2. 作用: 把block保存到对象中,恰当时机的时候才去调用

    3. 注意:这里容易引发循环引用,引起原因前面讲过,如何解决(weakself),不再赘述.

  2. block成为方法参数:传入一个block参数
    1. 举例:

        - (void)eat:(void(^)(int))block;
      - (void)eat:(nsstring *)block;
      
    2. 作用: 把block当做方法的参数使用,外界不调用,都是方法内部去调用,Block实现交给外界决定.(注意理解)

  3. 成为返回参数:该方法返回一个block
    1. 举例:

      - (void(^)(int))run;
      -(nsstring *)run;
      
    2. 作用:把block当做方法的返回值,目的就是为了代替方法,block交给内部实现,外界不需要知道Block怎么实现,只管调用

举例使用:

//Person.h

#import <Foundation/Foundation.h>
// name:类型的别名
typedef void(^BlockName)();

@interface Person : NSObject

//block作为属性
// block:既可以使用copy,也可以使用strong,但是建议用copy
// block类型:void(^)()
@property (nonatomic, strong) void(^operation)();

//block 作为参数
// 参数类型:block类型
- (void)eat:(void(^)())block;
- (void)eat2:(BlockName)block;
//传入参数block带返回值类型
- (void)eat3:(NSString *(^)(int))block;

//block作为返回值
- (void)run:(int)metre;
- (void(^)(int))run;
@end

#import "Person.h"

@implementation Person
- (void)eat:(void (^)())block
{
    block();
}
-(void)eat3:(NSString *(^)(int))block{
    block(3);
}
- (void)run:(int)metre
{
    NSLog(@"%d",metre);
}
- (void (^)(int))run
{
    return ^(int meter){
        NSLog(@"跑了%d米",meter);
    };
}
-(void)eat2:(BlockName)block{
    block();
}
@end

//viewcontroller

#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property (nonatomic, strong) Person *p;
@end

@implementation ViewController

//block作为方法返回值(代码在内部,调用在外部)
- (void)block3
{
    Person *p = [[Person alloc] init];
    [p run:2];
    //注意理解;p.run等价于[p run];
    //注意这两种调用结果一样,第二种是第一种的实现过程
    p.run(2);//调用方法:非常牛逼!!!!
    void(^run)(int) = p.run;
    run(2);
    //虽然p.run返回的是一个void(^)(int)类型的block,但这样写也对void(^run)(),没写参数就是参数都为0,run()就是传入参数为0
    void(^run2)() = p.run;
    run2();
}

//block作为方法参数(外部传代码,调用在内部)
- (void)block2
{
    Person *p = [[Person alloc] init];
    void(^block)() = ^{
        NSLog(@"吃东西");
    };
    [p eat:block];
    [p eat2:block];
    // 传入block给参数的Block赋值
    [p eat:^{
        NSLog(@"吃东西");
    }];
    //该block实现可以没有block返回类型:NSString *,但有更规范
    [p eat3:^NSString *(int a) {
        return [NSString stringWithFormat:@"该block实现中有返回值类型NSString,传入参数为:%zd",a];
    }];
}

//block作为属性(保存一段代码到对象中)
- (void)block1
{
    Person *p = [[Person alloc] init];
    void(^block)() = ^() {
        NSLog(@"执行对象中block");
    };
    p.operation = block;
    p.operation = ^(){
        NSLog(@"执行对象中block");
    };
    _p = p;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //执行对象中保存的block
    _p.operation();
}

@end
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容

  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,768评论 0 23
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,638评论 18 399
  • Block基础回顾 1.什么是Block? 带有局部变量的匿名函数(名字不重要,知道怎么用就行),差不多就与C语言...
    Bugfix阅读 6,766评论 5 61
  • Eureka是什么,SpringCloud用Eureka来干什么等等相关概念就不细说了,网上有大把大把的解释,甚至...
    liuyiyou阅读 1,171评论 0 50
  • 1、一个闲暇的午后,闲坐在咖啡馆跟我的好哥们聊了起来。问姜为什么总是一个人,这样独来独往不会感到孤独嘛!他却说:“...
    阿鹏讲情话阅读 292评论 0 4