iOS block 基本用法总结

来源:互联网 发布:mac连接电视 编辑:程序博客网 时间:2024/06/04 19:36

iOS block 基本用法总结

一、block定义

  • block定义:是OC中的一种数据类型,可以保存代码,传递参数等,被广泛的运用于iOS开发中。
  • ^是block的特有标记
  • block的实现方法的代码实在{}之间

  • block的定义(如下示例代码):

//声明形式 返回值(^块名称)(参数类型 参数名,参数类型 参数名,...)1.)不带参数的block    void(^noArgumentsBlock)() = ^{        NSLog(@"no Arguments");    };2.)单个参数的block   void(^oneArgumentBlock)(int) = ^(int n){    NSLog(@"%d", n); };      oneArgumentBlock(10); //传值3.)带行参的block    int (^sumBlock)(int, int) = ^(int a,int b){        return a+b;     };     int sum = sumblock(1,2); //调用 有返回值4.)typedef定义的block     typedef int(^SumBlock)(int,int);    SumBlock sumblock = ^(int a,int b){    //执行的方法    } 

二、Block使用

  1. block作为参数在NSArray中的运用
/**  *  查找字母为B的元素所在位置  *   enumerateObjectsUsingBlock与 for(... in ...)方法相比较,都是基于 NSFastEnumeration 实现的,在效率上基本一致,有时前者更快。 *  注意"enumerateObjectsUsingBlock" 修改局部变量时, 你需要声明局部变量为 __block 类型。 * 默认情况下,block外部的变量,在block中是只读的。 */ NSArray *array = @[@"A",@"B",@"C",@"D",@"E"];    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {        NSLog(@"数组的第%d个元素是%@", (int)idx, obj);        if ([obj isEqualToString:@"B"])        {            *stop = YES;            NSLog(@"字母为B的元素为第%d个", (int)idx);        }    }];    __block BOOL flag = NO;    [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {        if ([obj isEqualToString:@"B"])        {            *stop = YES;            flag = YES;//__block类型才能进行修改        }    }];    //值得注意的是 block是不允许修改外部变量的值,也就是不能修改栈中指针的内存地址,_block所起到的作用是将改变量的在栈中的内存放到了堆中。

2.block作为参数在NSDictionary中的运用

/**  *  查找Value为Bob所对应的key * 遍历字典时 enumerateObjectsUsingBlock 效率高 *  注意"enumerateObjectsUsingBlock" 修改局部变量时, 你需要声明局部变量为 __block 类型。 * 默认情况下,block外部的变量,在block中是只读的。 */ NSDictionary *dictionary = @{                     @"A" : @"Amy",                   @"B" : @"Bob",                   @"C" : @"Catch",                   @"D" : @"Dany"  };    [dictionary enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {        if ([obj isEqualToString:@"Bob"])        {            *stop = YES;            NSLog(@"%@", key);        }    }];

3.block在传递参数中的运用

声明文件.h

#import <UIKit/UIKit.h>typedef void(^NumInputBackBlock)(NSString *sure, NSString *text);@interface NumberInputView : UIView@property (nonatomic, copy) NumInputBackBlock numInputBackBlock;@end

声明文件.m

//点击事件发送block传递参数- (void)sure:(UIButton *)sender{     _numInputBackBlock(@"sure",@"text");}

实现文件.m

NumberInputView *numInput = [[NumberInputView alloc]  init];numInput.numInputBackBlock = ^(NSString *state, NSString *text){        NSLog(@"%@, %@", state, text);    };

4.block的注意事项

  • 循环引用(retain cycle)
  • 去除blockt提示的告警
    修改(1):Capturing ‘keyBoard’ strongly in this block is likely to lead to a retain cycle
    ARC编译环境下,调用block外部的变量时需要做处理
    直接引用外部的变量,因为ARC的机制,会造成循环引用
    修改(2):Assigning retained object to weak variable;object will be released after assignment
    这里写图片描述
    变量加上__weak修饰,变量在ARC中马上就会被释放,不会再block中执行。
    修改(3):
    这里写图片描述
    这样就解决了!

提示:一般在block中使用self 要在外部的对self进行处理,防止retain cycle的出现。处理方法如下:

__weak __typeof(&*self)weakSelf = self;__weak __typeof(self) weakSelf = self;__weak XxxViewController *weakSelf = self;__weak id weakSelf = self;

以上都可以!

1 0
原创粉丝点击