iOS block 基本用法总结

iOS block 基本用法总结

简书地址:http://www.jianshu.com/p/d89e19c08afb

一、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;

以上都可以!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值