Block的基本用法


NSString* (^myBlock)(NSString*, int);

myBlock = ^(NSString *name, int age){
    return [NSString stringWithFormat:@"My name is %@,I‘m %d years old!",name,age];
};

NSString *str = myBlock(@"胡曉偉",31);
NSLog(@"%@",str);

上面的例子演示了Block的基本用法,Block聲明的基本結構是:

返回類型 (^變量名)(參數列表..)

例如:

void (^myBlock1)(void);  //無返回值,無參數
void (^myBlock2)(NSObject, int); //有返回值,有參數
NSString* (^myBlock3)(NSString* name, int age); //有返回值和參數,並且在參數類型后面加入了參數名(僅為可讀性)

將一個Block定義為函數參數:

- (void)testBlock:(NSString *(^)(void)) myName
{
    NSLog(@"My Name is %@",myName());
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSString *(^myBlock)(void) = ^{ return @"wayne"; };
    
    [self testBlock:myBlock];
    
    return YES;
}

下面看看如何通過Block訪問不同上下文環境的局部變量:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSString *str = @"AAA";
    
    NSString *(^myBlock)(void) = ^(void){
        return str;
    };

    [self logBlock:myBlock];
    
    return YES;
}

- (void)logBlock:(NSString *(^)(void))block
{
    NSLog(@"%@",block());
}

下面的代碼測試了可變對象與不可變對象在Block中的情況:

NSString *str1 = @"str1";
NSMutableString *str2 = [NSMutableString stringWithString:@"str2"];

NSLog(@"************初始值與初始地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2);

void (^myBlock)(void) = ^{
    NSLog(@"************Block中輸出************");
    NSLog(@"【%@】,【%p】",str1,&str1);
    NSLog(@"【%@】,【%p】",str2,&str2);
};

str1 = @"str1_update";
[str2 appendString:@"_update"];
NSLog(@"************更新后的值與地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2);

myBlock();

NSLog(@"************調用Block后的值與地址************");
NSLog(@"【%@】,【%p】",str1,&str1);
NSLog(@"【%@】,【%p】",str2,&str2);

輸出結果:

************初始值與初始地址************

【str1】,【0xbff4d1f8】

【str2】,【0xbff4d1f4************更新后的值與地址************

【str1_update】,【0xbff4d1f8】

【str2_update】,【0xbff4d1f4************Block中輸出************

【str1】,【0xbff4d1e4】

【str2_update】,【0xbff4d1e8************調用Block后的值與地址************

【str1_update】,【0xbff4d1f8】

【str2_update】,【0xbff4d1f4

可以看出在Block內,不可變對象的值任然是初始化時的值,可變對象的值變成了新值。這是因為Block初始化在前,可變對象的修改在后;如果顛倒順序,先修改可變對象的值,再初始化Block,這樣Block就能同步修改后的值了。

最后看看Block對變量的訪問權限:

#import "AppDelegate.h"

@interface AppDelegate ()
{
    NSString *str1;
}
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSString *str2 = @"str2";
    
    __block NSString *str3 = @"str3";
    
    void (^myBlock)(void) = ^{
        
        str1 = @"newString"; //ok
        
        //str2 = @"newString"; //error
        
        str3 = @"newString"; //ok

        NSLog(@"%@,%@,%@",str1,str2,str3);
    };

    myBlock();
    
    return YES;
}

在Block里不能直接修改局部變量的值,如果要修改,需要在局部變量前加上修飾關鍵字__block。

從上面的例子可以看到在Block里能訪問並修改類變量、帶__block關鍵字的變量;但是不能修改不帶__block關鍵字的局部變量。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM