zoukankan      html  css  js  c++  java
  • Block回调使用和解析

    Block的本质是可以截取自动变量的匿名函数。
    本质和其他变量类似,但是存储的数据是一个函数体。
    可以像调用其他标准函数一样,传入参数,并得到返回值。
    脱字符 ^ 是块的语法标记
    按照调用函数的方式调用块对象变量就可以了:
    int result = myBlock(4); // result是 28

    • 参数是string 的代码块
     
    1. void (^printBlock)(NSString *x);  
    2. printBlock = ^(NSString* str)  
    3. {  
    4.     NSLog(@"print:%@", str);  
    5. };  
    6. printBlock(@"hello world!");  
     
    • 字符串数组排序
     
    1. NSArray *stringArray = [NSArray arrayWithObjects:@"abc 1", @"abc 21", @"abc 12",@"abc 13",@"abc 05",nil];  
    2. NSComparator sortBlock = ^(id string1, id string2)  
    3. {  
    4.     return [string1 compare:string2];  
    5. };  
    6. NSArray *sortArray = [stringArray sortedArrayUsingComparator:sortBlock];  
    7. NSLog(@"sortArray:%@", sortArray);  
     
    • 代码块的递归调用
    代码块想要递归调用,代码块变量必须是全局变量或者是静态变量,这样在程序启动的时候代码块变量就初始化了,可以递归调用
    static void (^ const blocks)(int) = ^(int i)  
    {  
        if (i > 0) {  
            NSLog(@"num:%d", i);  
            blocks(i - 1);  
        }  
    };  
    blocks(3);
     
    • 在代码块中使用局部变量和全局变量
    在代码块中可以使用和改变全局变量
    1. int global = 1000;  
    2. int main(int argc, const char * argv[])  
    3. {  
    4.     @autoreleasepool {  
    5.         void(^block)(void) = ^(void)  
    6.         {  
    7.             global++;  
    8.             NSLog(@"global:%d", global);  
    9.         };  
    10.         block();  
    11.         NSLog(@"global:%d", global);  
    12.     }  
    13.     return 0;  
    14. }  
    局部变量可以使用,不能改变
     
    不能编译通过
    1. int local = 500;  
    2. void(^block)(void) = ^(void)  
    3. {  
    4.       local++;  
    5.     NSLog(@"local:%d", local);  
    6. };  
    7. block();  
    8. NSLog(@"local:%d", local);  
     
    可以编译通过
    1. __block int local = 500;  
    2. void(^block)(void) = ^(void)  
    3. {  
    4.     local++;  
    5.     NSLog(@"local:%d", local);  
    6. };  
    7. block();  
    8. NSLog(@"local:%d", local);  
     

     
    • 需要回调数据的是A视图,那么B中应该定义block
    • BViewController.h
     
    //BViewController.h #import <UIKit/UIKit.h> typedef void(^CallBackBlcok) (NSString *text);// typedef定义 void(^) (NSString *text) 的别名为CallBackBlock @interface BViewController : UIViewController @property (nonatomic,copy)CallBackBlcok callBackBlock;// 使用自定义别名为CallBackBlock的block类型 -> 定义一个Block类型的变量 @end
     
     
     
    //BViewController.m - (IBAction)click:(id)sender { self.callBackBlock(_textField.text); //添加传参操作 [self.navigationController popToRootViewControllerAnimated:YES]; }
     
     
    // AViewController.m - (IBAction)push:(id)sender { BViewController *bVC = [self.storyboard instantiateViewControllerWithIdentifier:@"BViewController"]; bVC.callBackBlock = ^(NSString *text){ // 1 NSLog(@"text is %@",text); self.label.text = text; }; [self.navigationController pushViewController:bVC animated:YES]; }
     
     
    循环引用:
    AViewController创建并引用了BViewController,而BViewController引用CallBackBlock
     
    使用弱引用解除循环
    __weak AViewController *weakSelf = self; bVC.callBackBlock = ^(NSString *text){ NSLog(@"text is %@",text); // self.label.text = text; weakSelf.label.text = text; };
     
    为什么A中的block块能调用到B中的数据?
    B中声明了block变量,A中实现了block的具体代码,A将代码块作为参数传给B进行执行,因为B有执行代码所需要的参数string
     
     
     
     
     
     
     
     
  • 相关阅读:
    esper(4-5)- Context 条件
    esper(4-4)-OverLapping Context
    esper(4-3)-Non-Overlapping Context
    esper(4-2)-Category Context
    esper(4-1)-简单context
    esper(3)-窗口&聚合分组
    esper(2)-事件类型
    java常用代码
    idea(3)-jetty配置
    BP(反向传播)算法原理及推导
  • 原文地址:https://www.cnblogs.com/HackHer/p/8110507.html
Copyright © 2011-2022 走看看