IOSでのblockの使い方

8082 ワード

X.1初探Block
このセクションでは、blockの概念をいくつかの簡単な例でインポートします.
X.1.1 Blockの宣言と使用
「^」演算子を使用してblock変数を宣言し、blockの定義の一番後ろに「;」を付けて完全な文を表します(つまり、block定義全体を前の章で紹介した簡単な文と見なします.定義全体が完全な文でなければならないので、一番後ろにセミコロンを付けなければなりません).次はblockの例です.
   1: int multiplier = 7 ;
   2: int (^myBlock)( int ) = ^( int num)
   3: {
   4:     return num * multiplier;
   5: };

この例を下図で説明します(文字枠の字を以下に翻訳してください):
私たちは「myBlock」変数を宣言し、「^」記号でblockを表します.
これはblockの完全な定義で、この定義は「myBlock」変数に指定されます.
「myBlock」は、エコー値が整数(int)のblockであることを示す.
パラメータがあり、型も整数です.
このパラメータの名前は「num」です.
これはblockの内容です.
注目すべき点はblockが自分で定義した範囲と同じ変数を使用できることであり、上の例ではmultiplierとmyBlockはいずれもある関数内で定義された2つの変数であることを想像することができる.つまり、この変数はいずれもある関数の2つの括弧「{」と「}」の中間のブロックであり、それらの有効範囲は同じであるため、したがってblockではmultiplierという変数を直接使用することができ、またblockを変数として定義する場合、一般的な関数のように直接使用することができます.
   1: int multiplier = 7 ;
   2: int (^myBlock)( int ) = ^( int num)
   3: {
   4:     return num * multiplier;
   5: };
   6: printf ( "%d" , myBlock( 3 ));
   7: //      21

X.1.2直接Block使用
多くの場合、blockを変数に宣言する必要はありません.逆に、blockを使用する必要がある場所で直接埋め込み方式でblockの内容を書くことができます.次の例ではqsort_b関数、これは伝統的なqsort_に似ています.t関数ですが、blockを直接パラメータとして使用します.
   1: char *myCharacters[ 3 ] = { "TomJohn" , "George" , "Charles Condomine" };
   2: qsort_b (myCharacters, 3 ,
   3:          sizeof ( char *),
   4:          ^( const void *l, const void *r)//block  
   5:             {
   6:                 char *left = *( char **)l;
   7:                 char *right = *( char **)r;
   8:                 return strncmp (left, right, 1 );
   9:             }                            //end
  10: );

X.1.3 __ブロック変数
一般的に、block内では同じ役割ドメインの変数しか読み取れず、block外で定義された変数を修正することはできません.この場合、これらの変数がblockで修正されるようにするには、前に__を掛けなければなりません.blockの修飾語は、上記の第1例のmultiplierで言えば、この変数はblockで唯読なのでmultiplier=7指定が完了すると、blockでのmultiplierは7でしか修正できませんが、blockでmultiplierを修正すると編集時にエラーが発生しますので、blockでmultiplierを修正したい場合は、Multiplierの前に__を付けなければなりませんblockの修飾語は、次の例を参照してください.
   1: __block int multiplier = 7 ;
   2: int (^myBlock)( int ) = ^( int num)
   3: {
   4:   if (num > 5 )
   5:   {
   6:       multiplier = 7 ;
   7:     }
   8:     else
   9:     {
  10:         multiplier = 10 ;
  11:     }
  12:     return num * multiplier;
  13: };

 
ブロックの使用例コード
- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 200)];

    view.backgroundColor = [UIColor yellowColor];

    [self.view addSubview:view];



    void (^blockAnimation)() = ^(){

        view.frame = CGRectMake(100, 100, 100, 200);

    };

    void (^blockFinished)(BOOL finished) = ^(BOOL finished){

        view.frame = CGRectMake(0, 0, 100, 200);

    };

    [UIView animateWithDuration:1.0 animations:blockAnimation completion:blockFinished];

    

}

 パラメータ付きblockサンプルコード
および
blockを関数パラメータのサンプルコードとする
- (void)viewDidLoad

{

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    int (^ blockAdd)(int a, int b) = ^(int a, int b){

        return a+b;

    };

    

    int numA = 1;

    int numB = 2;

    int numSum = blockAdd(numA, numB);

    NSLog(@"%d", numSum);

    [self testFuncionUsingBlock:blockAdd];

    

    int (^ blockSub)(int, int) = ^(int a, int b){

        return a - b;

    };

    [self testFuncionUsingBlock:blockSub];

}



- (void)testFuncionUsingBlock:(int (^)(int, int))block

{

    int a = 3;

    int b = 4;

    NSLog(@"%d", block(a, b));

}