ConcurrencyのBlockの定義と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;
};

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

二、Blockにおけるオブジェクト変数へのアクセス


1.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;
    }];

}

2.selfオブジェクトのアクセス1次のコードで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); 
}

3.クラスの属性は1つのクラスにアクセスし、1つのオブジェクトの属性にアクセスする際に注意する必要があります.
 #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修飾.