block語法

一、block應(yīng)用范圍

1、動畫的轉(zhuǎn)場
2、網(wǎng)絡(luò)的事件處理
3、兩個對象或者多個對象之間的通訊
4、多線程的處理
(從iOS4.0開始就應(yīng)用得非常廣泛)

二、Block

block和C語言中的函數(shù)(函數(shù)指針)有些類似,但需要編譯器和運行時的堆或棧的支持,主要用在回調(diào)函數(shù)的地方,當(dāng)兩個對象進行通訊需要回調(diào)的時候廣泛應(yīng)用block,在一些小的操作當(dāng)中可以很好代替代理來作為回調(diào)操作的支撐。

三、Block和C語言函數(shù)指針的區(qū)別

 /*
  C 函數(shù)指針 typedef 定義
  typedef  int (*  SumBlockT)(int a);
*/ 
int (*  AFunc) (int   a) //C 函數(shù)指針 


/*
  Block   typedef 定義
  typedef  int (^  SumBlockT)(int a, int b);
*/ 
 int (^  BFunc) (int a, int b)  // Blocks

四、調(diào)用Block

    void (^ myblock_1)(void); //申明block,變量是myblocks_1
    void (^ myblock_2)(void) = NULL; //申明block,myblocks_2賦值為空
    myblock_2 = ^(void)
    {
        NSLog(@"只是賦值,可以說是這block函數(shù)塊賦值給myblocks_2");
    };
    myblock_2(); //執(zhí)行myblock_2  ,運行結(jié)果如下。
block—1.png
  int (^ myblock_3)(int a,int b) =^(int a, int b)
    {
        int c = a+b;
    
        return c;
    };
    int a = myblock_3(10,20);
    NSLog(@"%d",a);
block_2.png
_ _block int sum = 0;
int (^myblock4)(int a, int b) =^(int a ,int b){
    
    sum = a+b;
    return sum;
};
myblock4(20,30);
NSLog(@"%d",sum);
block_3.png
// 定義block 的 typedef
typedef int (^SumBlock)(int a, int b);
SumBlock myblock5 = ^ (int a,int b){
    NSLog(@"%d",a+b);
    return 0;
};
myblock5(50,10);

五、兩個代理之間通過Block通訊

Dog 跟 Person 之間的通訊

Dog.h文件
#import <Foundation/Foundation.h>

@interface Dog : NSObject
{
    int _ID;
    int _barkCount;
    NSTimer * timer;//定時器,定時發(fā)送信息
    //定義一個block變量
    void (^ BarkCallback)(Dog * thisDog,int count);
}
@property (assign)int ID;

//向外暴露一個函數(shù) setBark: ,給 person 對象使用
-(void) setBark:( void (^)(Dog * thisDog,int count))eachBrak;

@end

#pragma mark  ----------Dog.m 文件-------------------------------------------
#import "Dog.h"
@implementation Dog
@synthesize ID = _ID;

-(id)init
{
  self = [super init];

  if (self) {
      timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
  }
  return self;
}

-(void)updateTimer:(id)arg
{
    _barkCount++;
    NSLog(@"dog_ID %d barkCount %d",_ID ,_barkCount);

      //給 person 匯報一下
    // 調(diào)用 person 里面的 block
    if (BarkCallback) {
        BarkCallback(self,_barkCount);//調(diào)用從person傳過來的block
    }
}

-(void) setBark:( void (^)(Dog * thisDog,int count) )eachBrak
{
    BarkCallback = nil;
    BarkCallback = [eachBrak copy];
}

-(void)dealloc
{
    BarkCallback = nil;
}
@end

#pragma mark  ----------Person.h 文件-------------------------------------------
#import <Foundation/Foundation.h>
#import "Dog.h"

@interface Person : NSObject
{
    Dog *_dog;
}
@property(retain) Dog *dog;

@end


#pragma mark  ----------Person.m 文件-------------------------------------------
#import "Person.h"
@implementation Person

@synthesize dog = _dog;

-(void) setDog:(Dog *)dog
{
    if (_dog != dog){
        _dog = nil;
        _dog = dog;
    
        [_dog setBark:^(Dog *thisDog, int count) {
            NSLog(@"person dog^ID %d count %d",[thisDog ID],count);
        }];
    }
}

-(Dog *) dog
{
    return _dog;
}

-(void)dealloc
{
    self.dog = nil;
}

@end


#pragma mark  ----------main.m 文件 實現(xiàn)-------------------------------------------
Person * xiaoLi = [[Person alloc] init];

Dog *dog = [[Dog alloc]init];

[dog setID:10];

[xiaoLi setDog:dog];

while (1) {
    [[NSRunLoop currentRunLoop]run];
}

輸出結(jié)果如圖下:

圖1.png

六、_ _block關(guān)鍵字

一個block內(nèi)部可以引用自身作用外域的變量(static變量、extern變量、自由變量),定義變量時,不加存儲修飾符,默認(rèn)是自由變量(auto),auto變量保存在stack中,除了auto還存在register、static等存儲修飾符;自由變量在 Block 中是只讀的,在引入 block 的同時,還引入來一種特殊的 _ _block關(guān)鍵字變量存儲修飾符。

七、block 塊回調(diào)產(chǎn)生的強引用

上面的第五demo只是一部分,在實際開發(fā)過程中,比如很多網(wǎng)絡(luò)請求的操作是要執(zhí)行回調(diào)提供UI使用的,這個時候就會產(chǎn)生強引用內(nèi)存泄漏的問題,雙方互相持有,由于強引用的關(guān)系雙方都沒有其中一方去執(zhí)行釋放,這個時候就是雙向強引用所產(chǎn)的問題。

那么在很多OC 或者 Swift 的語法上也有很多用到了 block 回調(diào),為什么沒有產(chǎn)生強引用內(nèi)存泄漏的問題呢,那是因為官方在語法內(nèi)部做了操作,總的來說就是把雙向強引用變成單向強引用,也就是有其中一方變成了弱引用先釋放掉了,另一方自然也就釋放掉了。

下面舉個例子,把雙向強引用變成單向強引用,也是最常的block回調(diào)操作之一

@implementation ViewController
-(void)working
{
    //執(zhí)行網(wǎng)絡(luò)數(shù)據(jù)請求并回調(diào)
    NetWork  * net_joke = [[NetWork alloc]init];
    __weak typeof(net_joke) net = net_joke;  /// 強引用變成弱引用
    // net_joke 的變成弱引用 net 在執(zhí)行完block回調(diào)操作后,net_joke就會釋放

    NSMutableArray * model_Array = [NSMutableArray array];

    [net setBark:^(NSDictionary *dic) {
    
        NSArray * result = dic[@"result"];
       // int count = 0;
    
        if (result) {
            for (NSDictionary * jokeDic in result) {
            
                Joke_Model * joke = [[Joke_Model alloc]init];
                [joke setTitle:jokeDic[@"title"]];
                [joke setContent:jokeDic[@"content"]];
                [model_Array addObject:joke];
            
                Joke_Model * j = [[Joke_Model alloc]init];
                j = model_Array[count];
               // count++;
            
                NSLog(@"%@,\n%@",j.title,j.content);
                joke = nil;
                j = nil;
             }
        }
    }];
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

  • block 語法 block語法 -> 塊語法標(biāo)準(zhǔn)C里面沒有Block, C語言的后期擴展版本, 加入了匿名函數(shù);...
    李小六_閱讀 13,005評論 4 12
  • Block 語法 Block字面量 可以省略return type 當(dāng)return type和參數(shù)都為空時 Blo...
    沈冰忱閱讀 2,079評論 1 1
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,697評論 18 399
  • 垃圾對象的判定 引用計數(shù) 一個對象被引用計數(shù)器加一,取消引用計數(shù)器減一,引用計數(shù)器為0才能被回收。優(yōu)點:簡單。缺點...
    738bc070cd74閱讀 349評論 0 1
  • 今晚繼續(xù)讀《裂變式創(chuàng)業(yè)》,對其中一個章節(jié)《老板必須親自招人》有非常大的感觸。 不得不贊宗毅是一個多么難得的好老板,...
    暖暖的魔羯麻麻閱讀 277評論 0 0

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