UI_Block傳值

#import "AppDelegate.h"

#import "RootViewController.h"

@interface AppDelegate ()


@end


@implementation AppDelegate



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    

    RootViewController *rootVC = [[RootViewController alloc]init];

    

    UINavigationController *naVC = [[UINavigationController alloc]initWithRootViewController:rootVC];

    

    self.window.rootViewController = naVC;

    

    

    

    

    

    

    

    

    self.window.backgroundColor = [UIColor whiteColor];

    [self.window makeKeyAndVisible];

    return YES;

}

@end



#import "RootViewController.h"

#import "TwoViewController.h"


    //typedef之後,該block的別名就是block的名稱

typedef void(^argBlock)();


typedef void(^senderBlock)(NSString *str);



@interface RootViewController ()


@property(nonatomic,copy)argBlock circleBlock;


@end


@implementation RootViewController


    //block作爲方法的參數,作爲方法參數的時候,必須使用typedef修飾

-(void)testBlockWithBlock:(argBlock)senderBlock name:(NSString *)name{

    NSLog(@"name---%@",name);

        //block作爲參數的時候,和普通類型一樣的,普通類型是需要我們使用該參數,block類型是需要我們調用該參數block

    senderBlock();

}


    //帶參數的block作爲一個方法的參數

-(void)myBlockWithBlock:(senderBlock)sender{

        //將一個字符串傳遞出去

    sender(@"我是要傳遞出去的字符串");


}



- (void)viewDidLoad {

    [super viewDidLoad];

    self.navigationItem.title = @"Block學習";


        //使用typedefblock

    argBlock typeBlock = ^(){

        NSLog(@"MLGBWC,我是typedef");

    };

    typeBlock();

    

    

        //調用帶block參數的方法

    [self testBlockWithBlock:^{

        NSLog(@"參數block");

    }name:@"name"];

    

    

//__block外部串值        //block方法傳遞參數

    __block NSString *Vstr = nil;

    [self myBlockWithBlock:^(NSString *str) {

        Vstr = str;

        NSLog(@"str---%@",str);

    }];

    NSLog(@"Vstr---%@",Vstr);

    

    

    

    

    

 

//Block的學習

//第一種:  無返回值無參數的block定義以及實現

        //void(^)(void) 當前block的類型

        //block的名稱爲 oneBlock,類似於C語言中的函數名

        //賦值號左邊爲block聲明,右邊爲實現

    void (^oneBlock)(void) = ^(){

        NSLog(@"Hello World");

    

    };

    //調用block   不管有沒有參數,都需要書寫小括號

    oneBlock();

        //調用外部的block

    

    

//第二種:  有返回值無參數的block聲明及實現

        //有返回值的block需要在實現體內 return返回值

    int (^twoBlock)(void) = ^(){

        return 1000;

    };

        //調用block

    int b  = twoBlock();

    NSLog(@"b---%d",b);

    

    

//第三種:  無返回值有參數的block聲明及實現

    void(^threeBlock)(NSString *name) = ^(NSString *bb){

        NSLog(@"我是bb--%@",bb);

    };

        //調用block

    threeBlock(@"aaaaaaa");


//第三種://兩個參數的block

    void(^fourBlock)(NSString *name,NSString *sex) = ^(NSString *cc,NSString *dd){

        

        NSLog(@"%@,%@",cc,dd);

            //拼接

        NSString *pinjie = [cc stringByAppendingString:dd];

        NSLog(@"%@",pinjie);

            //拼接.2方法,一般拼接文件路徑

        NSString *pinjie2 = [cc stringByAppendingPathComponent:dd];

        NSLog(@"%@",pinjie2);

    };

        //調用

    fourBlock(@"Han",@"OBa");



//第四種:  有返回值有參數的block聲明及實現

    NSString *(^fiveBlock)(NSString *name) = ^(NSString *name){

        return name;

    };

        //調用

    NSString *name = fiveBlock(@"口鼻");

    NSLog(@"%@",name);

   

    

    //block實現體內 使用外部變量

    //當我們需要在block實現體內 對外部的局部變量做更改的時候,需要在局部變量的聲明之前加雙下劃線block(__block).未添加__block修飾的局部變量,block並沒有持有該變量,所以block只能使用該變量,但是不能做更改。使用__block修飾的局部變量,在block實現體 使用的時候,block是真正持有該變量,所以可以做修改

   //__block修飾的局部變量,實際上是將該變量的作用域範圍擴大了一些,不光能在ViewDidLoad方法中使用該變量,也可以在block函數的作用域中使用該變量

    __block int k = 1000;

        //聲明並實現一個block

    void (^myBlock)(void) = ^(){

        NSLog(@"k-----%d",++k);

    };

    myBlock();

        NSLog(@"%d",k);


 

    //block的循環引用,有可能會造成內存泄露

    //blockself的一個屬性的時候,我們在block實現體內需要使用到self得時候,有可能會造成循環引用,導致的結果爲self的引用計數有可能爲2,釋放不掉,造成內存泄露。所以我們需要使用__weak關鍵字來修飾self對象,讓該對象在block實現體內不需要內存管理,這個時候引用計數也就不會增加。

    //ARC下使用__weak,MRC下使用__block修飾。

    

    __weak RootViewController *my_self = self;

    self.circleBlock = ^(){

    my_self.navigationItem.title =@"AAA";

    };

    

    

//右按鈕

    UIBarButtonItem *rightButton = [[UIBarButtonItem alloc]initWithTitle:@"跳轉" style:UIBarButtonItemStylePlain target:self action:@selector(rightAction:)];

    self.navigationItem.rightBarButtonItem = rightButton;

    

    

    

    

}

/*

//在方法外部聲明並實現block       (瞭解知道就ok)

void (^outBlock)(void) = ^(){

    NSLog(@"外面的block");

};

*/



//右按鈕回調方法

-(void)rightAction:(UIBarButtonItem *)sender{

    NSLog(@"跳轉到下個界面");

    TwoViewController *twoVC = [[TwoViewController alloc]init];

    

    //調用two頁面的block,接收block的參數值

    twoVC.passSender = ^(NSString *str){

        NSLog(@"title-----%@",str);     //打印,用於查看是否將值傳遞過來了

        self.navigationItem.title = str;

    };

    


    [self.navigationController pushViewController:twoVC animated:YES];

}














- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


@end




#import "TwoViewController.h"


@interface TwoViewController ()


@end


@implementation TwoViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    self.navigationItem.title = @"MLGBWC";

    

//左按鈕

    UIBarButtonItem *leftButton = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStylePlain target:self action:@selector(leftAction:)];

    self.navigationItem.leftBarButtonItem = leftButton;

    

    

    

}


//左按鈕的回調方法

-(void)leftAction:(UIBarButtonItem *)sender{

    NSLog(@"返回上一個界面");

    

    //使用block將該界面的值傳遞到上個界面

    self.passSender(@"標題");

    

    

    

    

    [self.navigationController popViewControllerAnimated:YES];

}







- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


/*

#pragma mark - Navigation


// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/


@end



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章