首页 关于 微信公众号
欢迎关注我的微信公众号

ios中的block

Block的定义

有返回值&有两个参数

利用block做两个数个数相减。

NSInteger (^subtract)(NSInteger,NSInteger) = ^(NSInteger paramValue,NSInteger paramFrom){
    return paramFrom - paramValue;
};

有返回值&有一个参数

将数字转化成字符串。

NSString* (^intToString)(NSInteger) = ^(NSInteger paramInteger){
    NSString *result = [NSString stringWithFormat:@"%lu",(unsigned long)paramInteger];
return result;
};

无返回值&无参数

定义一个空的block 。

void (^simple)(void) = ^{
    /* Implement the block object here */
};

Block中对象变量的访问

block作用域

在block内部不能改变block作用域外的变量,若要改变,则必须用__block修饰该变量。

- (void)simpleMethod
{
   __block NSUInteger outsideVariable = 10;
    NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"obj1",@"obj2", nil];
    [array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        NSUInteger insideVariable = 20;

        outsideVariable = 50; // 若outsideVariable没有用__block修饰,则此处赋值报错。

        NSLog(@"Outside variable = %lu",(unsigned long)outsideVariable);
        NSLog(@"Outside variable = %lu",(unsigned long)insideVariable);
        return NSOrderedSame;
    }];

}

block访问self对象

在以下代码中可以访问self对象

- (void)simpleMethod
{
   __block NSUInteger outsideVariable = 10;
    NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"obj1",@"obj2", nil];
    [array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSLog(@"self = %@",self);
        return NSOrderedSame;
    }];

}

而在以下的代码中,我们却不能访问self对象

void (^test)(void) = ^{
    NSLog(@"self = %@",self);  // 报错
};

我们把以上代码修改成为以下这样,就可以访问self对象了:

void (^test)(id) = ^(id self){
    NSLog(@"self = %@",self); 
}

类属性的访问

在一个类中,访问一个对象的属性时需要注意:

#import "AppDelegate.h"
@interface AppDelegate()
@property (nonatomic, copy) NSString *stringProperty;
@end
@implementation AppDelegate

我们可以在以下代码中访问stringProperty属性

- (void) simpleMethod{
NSMutableArray *array = [[NSMutableArray alloc]
                         initWithObjects:@"obj1",
@"obj2", nil];
[array sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSLog(@"self = %@", self);
    self.stringProperty = @"Block Objects";
    NSLog(@"String property = %@", self.stringProperty);
    /* Return value for our block object */
return NSOrderedSame; }];
}

但是在以下代码中却不能访问stringProperty属性

void (^incorrectBlockObject)(id) = ^(id self){ NSLog(@"self = %@", self);
/* Should use setter method instead of this */ self.stringProperty = @"Block Objects"; /* Compile-time Error */
        /* Should use getter method instead of this */
NSLog(@"self.stringProperty = %@", self.stringProperty); /* Compile-time Error */
};

所以我们在以上代码块中需要利用setter和getter方法来访问类的属性。

inline block objects copy the value for the variables in their lexical scope. 以下代码:

typedef void (^BlockWithNoParams)(void); - (void) scopeTest{
        NSUInteger integerValue = 10;
        BlockWithNoParams myBlock = ^{
            NSLog(@"Integer value inside the block = %lu",
(unsigned long)integerValue); integerValue = 20;
        /* Call the block here after changing the
         value of the integerValue variable */
        myBlock();
        NSLog(@"Integer value outside the block = %lu",
(unsigned long)integerValue);
}

输出结果为:

10,20;

若想改变integerValue的值,则需要在变量前面添加__block修饰。

Blog

Opinion

Project