block的使用


一、block(块)的定义

block是一种类型,封装了一段代码块,可以在任何时候执行,block也可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。block与函数类似,只不过是直接定义在另一个函数里,和定义它的那个函数共享同一个范围内的东西。block用“^”符号来表示,后面跟着一对花括号,括号里面是block的实现代码,例如

^{
  // block的代码实现
}

二、block的使用

1、不带参数,空返回值的block

int num = 100;
    __block int num1;
    
    //不带参数,空返回值
    void(^MyBlock)() = ^()
    {
        NSLog(@"----");
        NSLog(@"----");
        //num =10; block中不能修改局部变量
        NSLog(@"---%d---",num);
        
        num1 = 30;
        NSLog(@"---%d---",num1);
    };
    
    MyBlock();

block能捕获变量,但不能在block中修改变量,不过如果在声明变量的时候加上__block修饰符,这样就可以在block中修改了。


2、带参数,空返回值的block

void(^LineBlock)(int)= ^(int n)
    {
        for(int i =0;i<n;i++)
        {
            NSLog(@"+++++++");
        }
    };
  
    LineBlock(9);

3、有返回值,带多个参数

int(^SumBlock)(int,int) = ^(int a,int b)
    {
        return a+b;
    };
    
    int sum = SumBlock(9,10);
    NSLog(@"sum = %d",sum);

4、用typedef定义类型

//用typedef声明类型再定义变量
typedef int(^MyMathBlock)(int,int);

MyMathBlock minus = ^(int a,int b)
    {
        return a-b;
    };
    
    NSLog(@"minus = %d",minus(11,9));

5、block与指针函数对比

//定义一个函数
int sum3(int a,int b)
{
    return a+b;
}

 /*
  指针函数
  */
    
int (*p)(int,int) = sum3;
    
NSLog(@"函数指针使用 sum=%d",p(100,20));

typedef类型的函数

typedef int(*myMath)(int,int);
myMath p1 = sum3;
    
NSLog(@"函数指针和typedef的使用 sum=%d",p1(1000,20));


6、inline block(内联块)

 /*
     *计算数组中等于2的个数
     *NSOrderedAscending:The left operand is smaller than the right operand(左边小于右边)
     *NSOrderedDescending:The left operand is greater than the right operand(左边大于右边)
     *NSOrderedSame:The two operands are equal(相等)
     */
    NSArray * array = @[@0,@1,@2,@3,@4,@5,@6];
    __block NSUInteger count = 0;
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        if ([obj compare:@2] == NSOrderedSame) {
            count++;
        }
    }];
    NSLog(@"count = %ld",count);
    return 0;

三、block(块)的深入

如果块所捕获的变量是对象类型,那么就会自动保留它。系统在释放这个块的时候,也会将其一并释放。其实块本事可视为对象,块本身也和其他对象一样,有引用计数,当最后一个指向块的引用移走后,块就被回收了,回收时也会释放块所捕获的变量,以便平衡捕获时所执行的保留操作

如果将块定义在类的实例方法中,那么除了可以访问类的所有实例变量外,还可以使用self变量。块定义在类中总能修改实例变量,所以声明时无需加__block。当通过读取或写入操作捕获了实例变量,那么也会自动把self变量一并捕获,因为实例变量与self所指代的实例关联在一起的。例如有个Person类

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic,assign) int age;
- (void)anInstanceMethod;
@end

#import "Person.h"

@implementation Person
- (void)anInstanceMethod
{
    void(^someBlock)() = ^{
        _age = 10;
        NSLog(@"age = %d",_age);
    };
    someBlock();
}
@end

#import <Foundation/Foundation.h>
#import "Person.h"
int main()
{
    Person *p = [[Person alloc] init];
    
    [p anInstanceMethod];

    return 0;
}

该代码的执行结果为:


如果Person类的某个实例正在执行anInstanceMethod方法,那么self变量就指向此实例,所以也可以通过self来访问实例变量

例如:self->_age = 10; 或者是 self.age = 10;





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值