Block的詳細(xì)使用(五)

Block 的初步理解

  1. 例如定義一個(gè)block:void(^myblock)(int);=>與int a;比較
  2. block的類型:void(^)(int);=>等價(jià)于int
  3. block的變量名:myblock=>等價(jià)于a
  4. 注意:
    1. 定義block時(shí)若有輸入?yún)?shù)(本例為int),參數(shù)名可有(int x)可無(wú)(int)但必須有參數(shù)的類型,但實(shí)現(xiàn)是必須有參數(shù)的類型和變量名.
    2. 實(shí)現(xiàn)block時(shí),也可以將block返回類型寫在實(shí)現(xiàn)中(通常不寫),寫在僅僅挨著^后面,不需要(),這樣有利于讓實(shí)現(xiàn)者知道該block返回什么值,(其實(shí)這樣寫更加規(guī)范,蘋果官方有使用:當(dāng)帶有返回值的block作為一個(gè)方法的參數(shù)時(shí),當(dāng)調(diào)用這個(gè)方法時(shí),系統(tǒng)的提示代碼在block實(shí)現(xiàn)中會(huì)加上返回類型,具體看典例)
 //實(shí)現(xiàn)中寫返回參數(shù)類型
    NSString *(^myblockx)(int) = ^NSString *(int a){
        return @"";
    };
    //實(shí)現(xiàn)中不寫返回參數(shù)類型
    NSString *(^myblockx2)(int) = ^(int a){
        return @"";
    };

定義一個(gè)block

  1. 無(wú)返回值有參數(shù)

     //定義一個(gè)block變量,然后給這個(gè)變量賦值:myblock
    //此時(shí)void(^)(int)為類型名,myblock1為變量名
    //int a ; a = 3;
    void(^myblock1)(int);
    myblock1 = ^(int a){
    };
    //定義一個(gè)block變量并賦值//int a = 3;
    void(^myblock2)(int) = ^(int a){
    };
    
  2. 無(wú)返回值無(wú)參數(shù)

      //1.先定義,在賦值
    void(^myblock0)();
    myblock0 = ^{
    };
    //2.定義時(shí)賦值(略)
    
  3. 有返回值無(wú)參數(shù)

     //1.先定義,在賦值(略)
    //2.定義時(shí)賦值
    int(^myblock4)()=^{
        return 3;
    };
    
  4. 有返回值有參數(shù)且參數(shù)(注意參數(shù)中可以有變量名也可以沒有變量名,變量名與實(shí)現(xiàn)時(shí)參數(shù)的變量名無(wú)關(guān)聯(lián))

     //1.先定義,在賦值
    int(^myblock7)(int c ,int d);
    myblock7 = ^(int a, int b){
        return a + b;
    };
    //2.定義時(shí)賦值
    int(^myblock6)(int ,int) = ^(int a, int b){
        return a + b;
    };
    
    
  5. 參數(shù)為block

    //重要:block的傳入?yún)?shù)為block類,理解!!!!
    //1.定義時(shí)賦值(參數(shù)block無(wú)變量名)
    //同理當(dāng)傳入?yún)?shù)為block時(shí),可以有變量名,也可以無(wú)變量名
    //傳入的block類型為void(^)():無(wú)返回值無(wú)參數(shù)型
    int(^blockx)(void(^)())= ^(void(^x)()){
        return 2;
    };
    //2.先定義,在賦值(參數(shù)block有變量名:mmm,參數(shù)block中的參數(shù)名q也是可有可無(wú))
    //傳入的block類型為int(^)(int):有返回值有參數(shù)型
    int(^blocky)(int(^mmm)(int q));
    blocky = ^(int(^x)(int a)){
        return 2;
    };
    

使用typedef定義block類

  1. 面向?qū)ο笏枷?將block定義成一個(gè)自定義類,然后使用這個(gè)類創(chuàng)建變量賦值block,使用typedef
//定義一個(gè)sumblock類(參數(shù)中的變量名可有可無(wú))
    typedef int(^sumblock)(int c ,int d);
    sumblock block = ^(int a,int b){
        return a + b;
    };
    //實(shí)質(zhì):
    // sumblock block;等價(jià)于 int(^block)(int,int);
    //用block替換掉sumblock;
    
    //舉例:定義一個(gè)blockz,傳入?yún)?shù)為sumblock類,然后賦值
    //sumblock只是類型,變量名可有可無(wú),也可以傳入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保存到對(duì)象中,恰當(dāng)時(shí)機(jī)的時(shí)候才去調(diào)用

    3. 注意:這里容易引發(fā)循環(huán)引用,引起原因前面講過(guò),如何解決(weakself),不再贅述.

  2. block成為方法參數(shù):傳入一個(gè)block參數(shù)
    1. 舉例:

        - (void)eat:(void(^)(int))block;
      - (void)eat:(nsstring *)block;
      
    2. 作用: 把block當(dāng)做方法的參數(shù)使用,外界不調(diào)用,都是方法內(nèi)部去調(diào)用,Block實(shí)現(xiàn)交給外界決定.(注意理解)

  3. 成為返回參數(shù):該方法返回一個(gè)block
    1. 舉例:

      - (void(^)(int))run;
      -(nsstring *)run;
      
    2. 作用:把block當(dāng)做方法的返回值,目的就是為了代替方法,block交給內(nèi)部實(shí)現(xiàn),外界不需要知道Block怎么實(shí)現(xiàn),只管調(diào)用

舉例使用:

//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 作為參數(shù)
// 參數(shù)類型:block類型
- (void)eat:(void(^)())block;
- (void)eat2:(BlockName)block;
//傳入?yún)?shù)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作為方法返回值(代碼在內(nèi)部,調(diào)用在外部)
- (void)block3
{
    Person *p = [[Person alloc] init];
    [p run:2];
    //注意理解;p.run等價(jià)于[p run];
    //注意這兩種調(diào)用結(jié)果一樣,第二種是第一種的實(shí)現(xiàn)過(guò)程
    p.run(2);//調(diào)用方法:非常牛逼!!!!
    void(^run)(int) = p.run;
    run(2);
    //雖然p.run返回的是一個(gè)void(^)(int)類型的block,但這樣寫也對(duì)void(^run)(),沒寫參數(shù)就是參數(shù)都為0,run()就是傳入?yún)?shù)為0
    void(^run2)() = p.run;
    run2();
}

//block作為方法參數(shù)(外部傳代碼,調(diào)用在內(nèi)部)
- (void)block2
{
    Person *p = [[Person alloc] init];
    void(^block)() = ^{
        NSLog(@"吃東西");
    };
    [p eat:block];
    [p eat2:block];
    // 傳入block給參數(shù)的Block賦值
    [p eat:^{
        NSLog(@"吃東西");
    }];
    //該block實(shí)現(xiàn)可以沒有block返回類型:NSString *,但有更規(guī)范
    [p eat3:^NSString *(int a) {
        return [NSString stringWithFormat:@"該block實(shí)現(xiàn)中有返回值類型NSString,傳入?yún)?shù)為:%zd",a];
    }];
}

//block作為屬性(保存一段代碼到對(duì)象中)
- (void)block1
{
    Person *p = [[Person alloc] init];
    void(^block)() = ^() {
        NSLog(@"執(zhí)行對(duì)象中block");
    };
    p.operation = block;
    p.operation = ^(){
        NSLog(@"執(zhí)行對(duì)象中block");
    };
    _p = p;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    //執(zhí)行對(duì)象中保存的block
    _p.operation();
}

@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 Blocks是C語(yǔ)言的擴(kuò)充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了這...
    小人不才閱讀 3,881評(píng)論 0 23
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,740評(píng)論 18 399
  • Block基礎(chǔ)回顧 1.什么是Block? 帶有局部變量的匿名函數(shù)(名字不重要,知道怎么用就行),差不多就與C語(yǔ)言...
    Bugfix閱讀 6,909評(píng)論 5 61
  • Eureka是什么,SpringCloud用Eureka來(lái)干什么等等相關(guān)概念就不細(xì)說(shuō)了,網(wǎng)上有大把大把的解釋,甚至...
    liuyiyou閱讀 1,452評(píng)論 0 50
  • 1、一個(gè)閑暇的午后,閑坐在咖啡館跟我的好哥們聊了起來(lái)。問(wèn)姜為什么總是一個(gè)人,這樣獨(dú)來(lái)獨(dú)往不會(huì)感到孤獨(dú)嘛!他卻說(shuō):“...
    阿鵬講情話閱讀 335評(píng)論 0 4

友情鏈接更多精彩內(nèi)容