Blockの学習記録

8407 ワード

^オペレータを使用して、block変数を宣言し、blockテキストの開始を示します.Block自体の本体は{}に含まれており、以下の例のように(通常はCを用いる;blockの終了を示す)
int (^myBlock)(int) = ^(int num){
        return 10*num;
    };
    
    NSLog(@"%d",myBlock(2));

以下は公式のblockに対する経典の解釈です
Block機能
blockは匿名のインラインコード集合体です.
1.関数と同様にパラメータタイプを持つ
2.推定および宣言された戻りタイプ
3.宣言が同じ役割ドメインにある状態をキャプチャできます.
4.同じ役割ドメイン範囲で定義されている他のblocksと共有して変更できます.
5.同じスコープ(スタックフレーム)が破棄された後も、同じスコープ(スタックフレーム)の状態を共有および変更し続ける
blockをコピーしたり、実行可能なパスとして他のスレッドに渡したり(自分のスレッド内でrun loopに渡したり)することができます.コンパイラと実行時には、blockライフサイクル全体ですべてのblock参照変数のコピーが保持されます.blocksは純CおよびC++で利用可能であるが、1つのblockも同様にObjective-Cのオブジェクトである.
Blockの用途
Blocksは、通常、非常に小さな、セルフパッケージのコードフラグメントを表す.したがって、カプセル化されたワークユニットとして同時実行されたり、1つのセットアイテム上で実行されたり、他の操作が完了したときにコールバックされたりする場合に便利です. 
Blocksは従来のコールバック関数の実用的な代替方法として、以下の2つの理由がある.
1.呼び出した場所でコードを記述して、後で実行する操作を実現することができます.従ってBlocksは通常フレームワーク法のパラメータとして用いられる. 
2.ローカル変数にアクセスできます.操作を実行するときにすべてのコンテキストの情報を統合するデータ構造を使用してコールバックする必要はありません.ローカル変数に直接簡単にアクセスできます.
同じようにblocksのタイプを作成することができます.同じ署名のblockを複数の場所で使用する場合、これは一般的に最善の方法とされています.
typedef float (^MyBlockType)(float, float);
    
    MyBlockType myFirstBlock = // ... ;
    
    MyBlockType mySecondBlock = // ... ;

Blockの閉包性(closure)
block内部では、ローカル変数、blockに渡されるパラメータ、グローバル変数/関数など、一般的な関数のようにデータにアクセスできます.またblockは閉パケット性を有するため、非局所変数(non-local variable)にもアクセスできる.非局所変数はblockの外に定義されるが,block内部にはその役割ドメインがある.たとえば、getFullCarNameでは、blockの前に定義されたmake変数を使用できます.
NSString *make = @"Honda";
NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    return [make stringByAppendingFormat:@" %@", model];
};
NSLog(@"%@", getFullCarName(@"Accord"));    // Honda Accord

非局所変数はconst変数でコピーされ、blockに格納されます.すなわち、blockは読み取り専用です.block内でmake変数に値を付与しようとすると、コンパイラエラーが投げ出されます.
constコピーで非局所変数にアクセスすることは、blockが実際に非局所変数にアクセスしているわけではないことを意味します.blockに非局所変数のスナップショットが作成されているだけです.blockを定義すると、非局所変数の値が何であれ凍結され、その後のコードで非局所変数の値が変更されても、blockはこの値を使用し続けます.次に、blockを作成した後、make変数の値を変更すると、何が起こるかをコードで見てみましょう.
NSString *make = @"Honda";
NSString *(^getFullCarName)(NSString *) = ^(NSString *model) {
    return [make stringByAppendingFormat:@" %@", model];
};
NSLog(@"%@", getFullCarName(@"Accord"));    // Honda Accord

// Try changing the non-local variable (it won't change the block)
make = @"Porsche";
NSLog(@"%@", getFullCarName(@"911 Turbo")); // Honda 911 Turbo

非ローカル変数の変更
凍結中の非局所変数は定数値であり、block内のコードが非局所変数に対して予期せぬ変更を防止できるため、デフォルトのセキュリティ動作でもあります.では、blockで非局所変数値を変更したい場合はどうすればいいのでしょうか.blockは修飾子(storage modifier)を格納して非局所変数を宣言する.
__block NSString *make = @"Honda";

参照による非局所変数へのアクセスは、通常の関数の静的局所変数(static local variable)と類似しています.block修飾子が宣言する変数は、blockが複数回呼び出された結果を記録することができる.たとえば、次のコードは、blockでiを加算するblockを作成します.
__block int i = 0;
int (^count)(void) = ^ {
    i += 1;
    return i;
};
NSLog(@"%d", count());    // 1
NSLog(@"%d", count());    // 2
NSLog(@"%d", count());    // 3

閉包性という概念は、関数が宣言したコンテキスト内の変数、さらには異なる実行コンテキストにアクセスできるようにすることです.
アクティブに呼び出します.

- (void)someMethod
{
BoolBlock ablock = ^(BOOL bValue) {
NSLog(@"Bool block!");
};

ablock();
}

パラメータとして返されます.

typedef void (^BoolBlock)(BOOL);
- (BoolBlock)foo()
{
BoolBlock ablock = ^(BOOL bValue) {
NSLog(@"Bool block!");
};
return [[ablock copy] autorelease];//   copy,       ,      ,        
}

クラスのメンバー:

@interface OBJ1 : NSObject
@property (nonatomic, copy)BoolBlock block;//     ,   
@end

OBJ1 *obj1 = ...
obj1.block = ^(BOOL bValue) {
NSLog(@"Bool block!");
};
       :

- (void)foo(BoolBlock block)
{
if (block) {
block();
}
}

他のblockのパラメータも:

BoolBlock bBlock = ^(BOOL bV){if(Bv){/*do some thing*/}};
HugeBlock hBlock = ^(BoolBlock bB) {bB();};

hBolck(bBlock);

グローバル変数:

static int(^maxIntBlock)(int, int) = ^(int a, int b){return a>b?a:b;};
int main()
{
printf("%d
", maxIntBlock(2,10)); return 0; }

blockでVC 1を転送する.H

@interface ViewController : UIViewController

@property(nonatomic, strong)UILabel *label;
@property(nonatomic, strong)UIButton *btn;

@end

VC1.M

- (void)viewDidLoad
{
    [super viewDidLoad];
	self.view.backgroundColor = [UIColor yellowColor];
    
    self.label = [[UILabel alloc]initWithFrame:CGRectMake(50, 50, 100, 50)];
    self.label.backgroundColor = [UIColor brownColor];
    [self.view addSubview:self.label];
    
    self.btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.btn.frame = CGRectMake(50, 250, 100, 50);
    self.btn.backgroundColor = [UIColor grayColor];
    [self.btn addTarget:self action:@selector(push) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.btn];
    
}

- (void)push{
    ViewController2* second = [[ViewController2 alloc] init];

    second.callback = ^(NSString *msg){
        self.label.text = msg;
    };

    [self.navigationController pushViewController:second animated:YES];
}

VC2.H
#import <UIKit/UIKit.h>

@interface ViewController2 : UIViewController

@property(nonatomic, strong)UIButton *btn;
@property(strong,nonatomic) void (^callback) (NSString* _msg);

@end

VC2.M

- (void)viewDidLoad
{
    [super viewDidLoad];
	self.btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.btn.frame = CGRectMake(50, 250, 100, 50);
    self.btn.backgroundColor = [UIColor grayColor];
    [self.btn addTarget:self action:@selector(pop) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.btn];
    
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    btn2.frame = CGRectMake(50, 170, 100, 50);
    btn2.backgroundColor = [UIColor blueColor];
    [btn2 addTarget:self action:@selector(send) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn2];
}

- (void)send{
    if (_callback) {
        _callback(@"123");
        _callback = nil;
    }
}

- (void)pop{
    
    [self.navigationController popViewControllerAnimated:YES];
}

blockはどこに置きます---IOSの中でスタックとスタックの違い


void foo()
{
    __block int i = 1024;
    int j = 1;
    void (^blk)(void);
    void (^blkInHeap)(void);
    blk = ^{ printf("%d, %d
", i, j);};//blk blkInHeap = Block_copy(blk);//blkInHeap } - (void)fooBar { _oi = 1; OBJ1* oj = self; void (^oblk)(void) = ^{ printf("%d
", oj.oi);}; void (^oblkInHeap)(void) = [oblk copy];//oblkInHeap }

勝手に文法を使うな


#import <UIKit/UIKit.h>   
@interface AppDelegate : NSObject <UIApplicationDelegate>
@property (nonatomic, strong) NSString *stringProperty;  
@end


#import "GCDAppDelegate.h" 
@implementation AppDelegate 
@synthesize stringProperty;  
- (void) BlockTestError{
HelloBlock myBlock= ^(void){
	self.stringProperty = @"Block Objects"; 
	NSLog(@"String property = %@", self.stringProperty);//    
};
myBlock();
}}  

- (void) BlockTestCorrect{
	HelloBlock myBlock= ^(void){
		[self setStringProperty:@"Block Objects"];
	    NSLog(@"self.stringProperty = %@", [self stringProperty]); //  ok
	};
myBlock();
}}  
@end

参考文章:Blockチュートリアルシリーズ初識block block伝値ios開発--blockが知っておくべきこと