[Objective-c]_[块语法的使用及应用场景]

本文介绍了Objective-C的块语法,强调其作为函数指针的特性,并展示了如何声明、定义和简化块的语法。通过例子说明块捕获变量的特性,以及在__block关键字的作用下如何在块内修改外部变量。此外,还讨论了块用作回调函数的情况,并给出了在项目中异步线程中应用块的例子。
摘要由CSDN通过智能技术生成

objective-c的块语法与函数类似,但作用类似于函数指针,并且可以直接转化成函数指针。


1.块语法的声明和定义

声明:

void (^blockReturningVoidWithVoidArgument)(void);
int (^blockReturningIntWithIntAndCharArguments)(int, char);
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);

或者通过typedef:

typedef float (^MyBlockType)(float, float);
 
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;

块的声明类似于c的函数,不同的地方是必须在块名前加^,而且要是没有返回值必须或参数都必须要加void.

定义:

float (^oneFrom)(float);
 
oneFrom = ^(float aFloat) {
    float result = aFloat - 1.0;
    return result;
};

也可以简化着写:

        float (^oneFrom)(float) = ^(float aFloat) {
            float result = aFloat - 1.0;
            return result;
        };


也可以这样声明定义:

@interface XYZObject : NSObject
@property (copy) void (^blockProperty)(void);
@end
实现:

    self.blockProperty = ^{
        ...
    };
    self.blockProperty();


2.在代码块中使用局部变量和全局变量

- (void)testMethod {
    int anInteger = 42;
 
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
 
    testBlock();
}
输出结果:Integer is: 42
块内是可以直接访问块外的变量。

再看下面代码:

   int anInteger = 42;
 
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
    };
 
    anInteger = 84;
 
    testBlock();
输出结果:Integer is: 42

输出结果没有变化,块只是捕获到一个常量值,这是因为块内的存储空间和非块内是不一样的,这是代码块的特点。若想改变可以用__block。定义一个__block变量就是让这个变量和块内共享内存空间,所以可以在块内修改并且影响到外部变量的值。

__block int anInteger = 42;
        
void (^testBlock)(void) = ^{

    NSLog(@"Integer is: %i", anInteger);

        };
        
   anInteger = 84;
        
    testBlock();<span style="color:#666666;">
</span>
输出结果: Integer is: 84

并且可以在块内改变:

   __block int anInteger = 42;
 
    void (^testBlock)(void) = ^{
        NSLog(@"Integer is: %i", anInteger);
        anInteger = 100;
    };
 
    testBlock();
    NSLog(@"Value of original variable is now: %i", anInteger);

输出结果:

Integer is:42

Value of original variable is now: 100


如果访问的对象是一个自定义的类类型呢?

自定义类类型:

test.h

#import <Foundation/Foundation.h>

@interface test : NSObject
{
    NSString *name;
}

@property (readwrite,assign) NSString * name;

@end
test.m

#import "test.h"

@implementation test

@synthesize name;

@end

        test *t = [test new];
        [t setName:@"123"];
        void (^testBlock)(void) = ^{
            NSLog(@"%@",[t name]);
            [t setName:@"456"];
            NSLog(@"%@",[t name]);
            test *t2 = t;
            [t2 setName:@"777"];
        };
        [t setName:@"789"];
        testBlock();

输出结果:

789

456


3.代码块用作回调函数

- (void)beginTaskWithCallbackBlock:(void (^)(void))callbackBlock
{
    callbackBlock();
}

调用;

 [self beginTaskWithCallbackBlock:^{NSLog(@"hello");}];

当有多个参数的时候,代码块必须要作为最后一个参数:

- (void)beginTaskWithName:(NSString *)name completion:(void(^)(void))callback;

4.应用场景

项目中经常遇到一些方法中的参数是代码块,如下:

异步线程:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
    NSLog(@"Block for asynchronous execution");
});


<pre name="code" class="objc">NSBlockOperation *block = [[NSBlockOperation alloc] init];
[block addExecutionBlock:^{
            sleep(1);
            NSLog(@"111");
        }];
[block start];


 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值