您的位置:首页 > 产品设计 > UI/UE

Block高级用法:Block传值UI_12(3)

2015-10-12 08:42 369 查看
1、简单复习Block的定义、赋值、调用做学习传值铺垫:
//声明一个函数 无返无参

void printfHello(int a);

//函数的实现

void printfHello(int a){

printf("hello wold\n");

}

//函数指针的类型

//void (*)(int);

//定义一个函数指针变量
void (*p)(int)
= printfHello;
//block是块语法,实质就是匿名函数
//定义一个block变量,block的定义和函数的定义很像
void (^myBlock)(int);

//函数的调用

printfHello(3);



//使用函数指针调用

p(1);



//给block变量赋值
myBlock = ^(int a){
NSLog(@"%d",a);

};



//block变量的调用
myBlock(10);
//无返无参
typedef void(^aBlock) ();

//使用重命名的block类型定义block变量

aBlock show = ^(){

NSLog(@"我是中国人");

};

//block调用
show();
======================Block传值========================

2、使用Block在两个界面之间传值(Block高级用法:Block传值)

使用Block的地方很多,其中传值只是其中的一小部分,下面介绍Block在两个界面之间的传值:
先说一下思想:

首先,创建两个视图控制器,在第一个视图控制器中创建一个UITextField和一个UIButton,其中UILabel是为了显示第二个视图控制器传过来的字符串,UIButton是为了push到第二个界面。

第二个界面的只有一个UITextField,是为了输入文字,当输入文字,并且返回第一个界面的时候,当第二个视图将要消失的时候,就将第二个界面上TextFiled中的文字传给第一个界面,并且显示在UITextField上。
———————————————————————————————————————

AppDelegate.m
self.window.rootViewController =
[[[UINavigationController alloc]initWithRootViewController:[FirstViewController new]]autorelease];
FirstViewController.m
#import "SecondViewController.h"
@interface FirstViewController ()

@property(nonatomic,retain)UITextField *textField;

@property(nonatomic,retain)UIButton *button;

@end

@implementation FirstViewController

- (void)dealloc{

self.textField = nil;

self.button= nil;

[super dealloc];

}

- (void)viewDidLoad {

[super viewDidLoad];

self.textField =
[[UITextField alloc]initWithFrame:CGRectMake(50, 100, 220, 30)];

self.textField.placeholder = @"请输入内容";

self.textField.borderStyle = UITextBorderStyleRoundedRect;

[self.view addSubview:self.textField];

[self.textField release];

self.button =
[UIButton buttonWithType:(UIButtonTypeSystem)];

self.button.frame = CGRectMake(100, 160, 120, 30);

[self.button setTitle:@"进入下一个界面" forState:( UIControlStateNormal)];
[self.view addSubview:self.button];
//添加方法
[self.button addTarget:self action:@selector(handlePush :) forControlEvents:(UIControlEventTouchUpInside)];
}

- (void)handlePush : (UIButton *)push{

SecondViewController *secondVC = [[SecondViewController alloc]init];
#warning 3 在push之前给block属性赋值
注意: 在block访问self,或者属性,或者使用self调用方法,都会造成对当前类的对象的引用计数+1,使用__blocktypeof(self)
weakSelf = self; block内部不会持有,也不会造成他的引用计数器+1
__block typeof(self)
weakSelf = self;
secondVC.passValue =
^(NSString *string){

//在block块内给空间赋值
weakSelf.textField.text = string;
};
[self.navigationController pushViewController:secondVC animated:YES];

[secondVC release];
}
————————————————————————————————
SecondViewController.h
#warning block 传值

#warning 1 给block起别名

typedef void(^passBlock)(NSString *);

//1.定义block类型起别名
typedef void (^aBlock)();
@interface SecondViewController : UIViewController
//2.定义block类型的属性

//block变量存在于栈区,用copy修饰后就会存放在堆区,从而保证block块不会丢失,但是申请了内存就要释放内存

@property(nonatomic,copy)aBlock testBlock;

//@property (nonatomic,copy)void (^testBlock2)();

#warning 2 定义block类型的变量

@property(nonatomic,copy)passBlock passValue;
@end
——————————————————————————————
SecondViewController.m
//1.给block类型起别名

typedef void(^aBlock) ();

@interface SecondViewController ()

@property(nonatomic,retain)UITextField *textField;
@property(nonatomic,retain)UIButton *button;
@end
@implementation SecondViewController

- (void)dealloc{

self.textField = nil;

self.button = nil;

Block_release(_testBlock);//block
属性释放

NSLog(@"第二个视图被销毁了");

[super dealloc];

}

- (void)sayHi{

NSLog(@"你好");

}

- (void)viewDidLoad {

[super viewDidLoad];

self.view.backgroundColor =
[UIColor cyanColor];



给block属性赋值
在block访问self,或者属性,或者使用self调用方法,都会造成对当前类的对象的引用计数+1
重点:第一种: //MRC
__block SecondViewController *weakSelf = self;
使用__block修饰的对象block内部不会持有,也不会造成他的引用计数器+1
第二种: //ARC
__weak SecondViewController *weakSelf1 = self;
第三种: __block typeof(self)
weakSelf3 = self;
__block typeof(self)
weakSelf3 = self;
self.testBlock =
^(){

[weakSelf3 sayHi];

};

self.textField =
[[UITextField alloc]initWithFrame:CGRectMake(50, 100, 220, 30)];

self.textField.placeholder = @"请输入内容";

self.textField.borderStyle = UITextBorderStyleRoundedRect;

[self.view addSubview:self.textField];

[self.textField release];

self.button =
[UIButton buttonWithType:(UIButtonTypeSystem)];

self.button.frame = CGRectMake(100, 160, 120, 30);
[self.button setTitle:@"返回上一个界面" forState:( UIControlStateNormal)];
//添加方法
[self.button addTarget:self action:@selector(handlePush
:) forControlEvents:(UIControlEventTouchUpInside)];



[self.view addSubview:self.button];



}

- (void)handlePush : (UIButton *)push{

//block的调用

// self.textBlock();



#warning 4 pop之前调用block块
self.passValue(self.textField.text);
[self.navigationController popViewControllerAnimated:YES];
}
最终效果:




————————————————————————————————————————
总结:
声明block的属性时,需要使用copy 在dealloc 中要使用对应的Block_release()
在block实现部分,不要直接self、实例变量、属性、会造成循环不能引用
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: