你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS --- 關於block的常見使用方法

iOS --- 關於block的常見使用方法

編輯:IOS開發綜合

Objective-C中的block有多種定義和使用方法.

作為property

@property (nonatomic, copy) int (^myBlock)(int a, int b);

block代碼體:

_myBlock = ^int (int a, int b) {
    return a + b;
};

使用:

sum = _myBlock(10, 20);

使用typedef

typedef int (^MyBlock)(int a, int b);
MyBlock myBlock = ^int (int a, int b) {
    return a * b;
};

使用:

int sum = myBlock(10, 20);

作為變量

int (^myBlock) (int a, int b) = ^int (int a, int b) {
    return a - b;
};
int sum = myBlock(10, 20);

此時myBlock可作為變量自由傳遞, 調用的時候myBlock(10, 20);即可.
如果想在block中對當前局部變量進行修改的話, 需要使用__block:

__block int sum = 0;
int (^myBlock)(int a, int b) = ^int (int a, int b) {
    sum = a + b;
    return sum;
}

block默認可訪問局部變量sum, 而不能修改, 以防出現循環引用的情況.
而__block對象在block中不會被其強引用一次, 所以不會出現循環引用.

__block與__weak

以上可知, 聲明block的時候只是把該sum局部變量復制了一份, 因此若其是一個指針, 則在block中修改其指向的內容不需要加__block.
__block修飾對象和基本數據類型, 而__weak只能修飾對象.
__block對象可在block中修改(重新賦值), 而__weak不行.
因此, 對於類的對象, 若要在block中對其屬性進行修改, 需要使用__weak. 如:

__weak MyClass *weakSelf = self;
_myBlock2 = ^(NSInteger count) {
     weakSelf.count = count;
}

作為方法調用的參數

預先聲明MyBlock及屬性myBlock2,

typedef int (^MyBlock)(int a, int b);
@property (nonatomic, copy) MyBlock myBlock2;

定義方法methodTakeBlock接收MyBlock.

- (int)methodTakeBlock:(MyBlock)block {
    int sum = 0;
    if (block) {
        sum = block(10, 20);
    }
    return sum;
}

則調用該方法的時候, 在其參數中實現該MyBlock實體:

sum = [self methodTakeBlock:^int (int a, int b) {
    return b / a;
}];

這種方式僅在implementation中即可.

在方法的聲明中寫明block類型

在interface中:

// 方法調用的參數
- (int)method2TakeBlock:(int (^) (int a, int b))block;

在implementation中:

- (int)method2TakeBlock:(int (^)(int, int))block {
    int sum = 0;
    if (block) {
        sum = block(10, 20);
    }
    return sum;
}

調用方法:

sum = [self method2TakeBlock:^int(int a, int b) {
    return a * b - b;
}];

在ViewController之間傳遞數據

在TestViewController.h中定義一個block, 用於從TestViewController跳轉至ViewController時修改ViewController中的label內容:

#import 

@interface TestViewController : UIViewController

typedef void(^BlockUpdateBtnTitle)(NSString *);
@property (nonatomic, copy) BlockUpdateBtnTitle blockUpdateBtnTitle;

@end

該block接收一個NSString參數.
點擊button觸發以下動作

- (IBAction)action:(UIButton *)sender {
    if (_blockUpdateBtnTitle) {
        _blockUpdateBtnTitle(@value changed by block);
    }

    [self dismissViewControllerAnimated:NO completion:nil];
}

在ViewController.m中傳遞block實體, 注意其接收參數要與定義的一致:

- (IBAction)action:(UIButton *)sender {
    TestViewController *testVC = [[TestViewController alloc] init];
    __weak ViewController *weakSelf = self;
    testVC.blockUpdateBtnTitle = ^(NSString *btnTitle) {
        weakSelf.lb.text = btnTitle;
    };
    [self presentViewController:testVC animated:NO completion:nil];
}

點擊button跳轉至TestViewController中, 在TestViewController中執行該blockUpdateBtnTitle, 進而修改ViewController中label的內容.
因在block中要對ViewController中的屬性進行修改, 因此可使用__weak來防止循環引用.

 

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved