iOS开发-Object-C Block的实现方式

前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量。你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观。顺带一提,苹果很多的接口(API)都使用了Block。

一、Block的基本定义

Block的基本写法(也是详细写法):

    returnType (^blockName)(params) = ^returnType(params) { // code... };

中文再解释:返回类型 (^Block的名字)(Block的参数) = ^返回类型(Block的参数) { 这里放代码 },例:

    int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){ return 100;};

如果你的Block不需要返回类型和参数,那么你可以简写为:

      void (^myBlock2)() = ^(){ };

  void (^myBlock2)(void) = ^void(void){ };

返回类型或参数,没有的话可以用“void”代替。
你也可以把等于号右边,^后的()删除,即是:

  void (^myBlock2)() = ^{ };

这样是不是很简洁?
你也可以先定义一个Block函数,但不写函数的实现,我们可以在后面再写具体函数的实现,像这样:

  void (^myBlock2)(void);myBlock2 = ^{ };

二、Block作为方法定义
把Block定义在方法里,与上面不同的是,Block的名字不需要在声明时写上,而是在后面,像这样:

    - (void)getWtihBlock:(void (^)())block{ // code... // 记得要调用block block();}

使用方法:

  [self getWtihBlock:^{ NSLog(@"sdf");}];

下面作了一个详细点的例子,并写了备注:

/* 追加自身字符串N次(每次复制前加一个换行\n)

  • @param string 字符串

  • @param count 追加次数

  • @param stringBlock 目标Block,其中str参数为结果字符串
    */
    // Block也可以定义在方法里,但是不需要定义Block的名字
    // IOS开发很多的API也用到了Block,像UIView的块动画

      - (void)getStrWithString:(NSString *)string 
                     CopyCount:(int)count 
                  resultString:(void (^)(NSString *str))stringBlock
    { 
          NSMutableString *newString = [NSMutableString stringWithString:string]; 
          for (NSUInteger i = 0; i < count; i++) { 
            NSUInteger len = [string length]; 
            NSString *insertString = [NSString stringWithFormat:@"\n%@", string]; 
            [newString insertString:insertString atIndex:len]; 
        } 
        stringBlock(newString);
    }
    

用法也是一样:

    BlockObject *block = [[BlockObject alloc] init];
    [block getStrWithString:@"Garvey" CopyCount:3 resultString:^(NSString *str) { 
    // str为处理后的结果 
      NSLog(@"str is %@", str); 
    }];

有时候复杂的Block语法会令到函数的声明难以阅读,所以会经常使用typedef对Block起一个新类型。

   typedef void (^ResultBlock)(NSString *str);

定义方法时就变成了:

- (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock;

让我们对比一下,使用typedef前后:

// 使用前

- (void)getStrWithString:(NSString *)string CopyCount:(int)count resultString:(void (^)(NSString *str))stringBlock;

// 使用后
- (void)getStrWithString2:(NSString *)string CopyCount:(int)count resultString:(ResultBlock)stringBlock;
注意:使用方法是一样的,只不过定义变得简单了。

如果你一直在使用代理(Delegate)进行方法回调,那么你现在可以尝试使用Block了。

int a = 10;
    void (^block)() = ^{
        a;
    };
    __weak void (^weakBlock)() = ^{
        a;
    };
    void (^stackBlock)() = ^{
        
    };
    NSLog(@"%@,%@,%@",block,weakBlock,stackBlock);
<__NSMallocBlock__: 0x170254c40>,
<__NSStackBlock__: 0x16fd6e0d8>,
<__NSGlobalBlock__: 0x10009c2e0>

可以看出,ARC对类型为strong且捕获了外部变量的block进行了copy。并且当block类型为strong,但是创建时没有捕获外部变量,block最终会变成NSGlobalBlock类型(这里可能因为block中的代码没有捕获外部变量,所以不需要在栈中开辟变量,也就是说,在编译时,这个block的所有内容已经在代码段中生成了,所以就把block的类型转换为全局类型),如果是weak类型的block,依然不会自动进行copy

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

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,581评论 18 399
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,757评论 0 23
  • iOS编程规范0规范 0.1前言 为􏰀高产品代码质量,指导广大软件开发人员编写出简洁、可维护、可靠、可 测试、高效...
    iOS行者阅读 4,435评论 21 35
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 3,776评论 1 10
  • 唇釉使用步骤️ 注意事项:使用之前先用自己的修纹膏(润唇膏)打底,30秒之后擦掉在涂唇釉! 使用方法一: 用唇刷点...
    何蓉阅读 610评论 0 0