界面通信

属性传值、协议传值、Block传值

?、属性传值

/**
 *  属性传值
    1、属性传值用于第一个界面向第二个界面传送值
    2、明确二者联系的桥梁,也就是触发跳转的地方
    3、明确传输的值 类型是什么
    4、在第二个视图控制器内部声明相对应类型的属性,来接收传输的值
    5、在第二个界面使用传入的值

*/

//第?步:在SecondViewController.h?定义?个contents字符串属性来保存由第一个界面传过来的字符串内容
@interface SecondViewController :
UIViewController
@property(nonatomic,copy)NSString *contents;

@end

//第?步:在点击FirstViewController按钮的?法?给SecondViewController的contents属性赋值
-(void)buttonAction:(UIButton *)button
{
    NSLog(@"进?第??");
    SecondViewController *secondVC =
    [[SecondViewController alloc] init];
    secondVC.contents = self.label.text;
    [self.navigationController
     pushViewController:secondVC animated:YES];
    [secondVC release];

}

//第三步:在SecondViewController使?contents属性给textField赋值
@implementation SecondViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    self.navigationItem.title = @"第??";
    self.textField = [[UITextField alloc] initWithFrame:CGRectMake(85, 200, 200, 40)];
    self.textField.placeholder = @"请输?内容";
    self.textField.text = self.contents;
    self.textField.borderStyle =
    UITextBorderStyleRoundedRect;
    [self.view addSubview:self.textField];
    [_textField release];

}

?、协议传值

第?步:声明协议

第?步:声明代理?

第三步:执?协议?法

第四步:签订协议

第五步:指定代理?

第六步:实现协议?法

//1、在 FourthViewController.h?声明协议

//UI中的协议名称为 当前类名 + Delegate
@protocol FourthViewControllerDelegate <NSObject>

//声明协议方法

@required //必须要实现的?法,默认是必须实现

- (void)pushValue:(NSString *)text;

@optional //可选实现的协议?法

- (void)pushColor:(UIColor *)color;

@end

//2、声明代理   必须是assign,使?retain,copy会导致循环引?问题

@property (nonatomic, assign) id<FourthViewControllerDelegate>delegate;

//3、执?协议?法
- (void)back {
   
    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(pushValue:)]) {
        [self.delegate pushValue:self.textField.text];
    }
   
    if (self.delegate != nil && [self.delegate respondsToSelector:@selector(pushColor:)]) {
        [self.delegate pushColor:self.view.backgroundColor];
    }
    [self.navigationController popViewControllerAnimated:YES];

}

//4、接收(签订)协议

@interface ThirdViewController : UIViewController<FourthViewControllerDelegate>

//5、指定当前对象为代理人
- (void)push {
    FourthViewController *fourthVC = [[FourthViewController alloc] init];
    //指定第二个界面的代理对象为第一个视图控制器
    fourthVC.delegate = self;
    [self.navigationController pushViewController:fourthVC animated:YES];
    [fourthVC release];

}

//6、实现协议方法,并接收传过来的值
- (void)pushValue:(NSString *)text {
    self.label.text = text;
}
- (void)pushColor:(UIColor *)color {
    self.view.backgroundColor = color;

}

三、Block传值

  • block是匿名函数,能够实现函数回调功能
  • ?于页?之间通信,同时可以进?传值

/**
     *  1、Block是一种数据类型,并且是一种自定义的数据类型
        2、Block的标志是^(托字符)
        3、Block是匿名函数,TA与函数最主要的区别在于,函数在编译期就已经知道封装了什么功能,但是Block只有当执行时才知道内部封装的功能,所以说Block更加灵活多变
        4、Block的作用也是封装代码段来实现具体的功能
        5、既然Block是匿名函数,所以赋值时,不能将函数名直接赋值,初值为函数的实现体。

*/

void(^block)(void) = ^(void)
{
};
其中:
1.void(^block)(void)是类型
2.block是变量名

3.^(void){};是block实现

//1.?参?返回值类型的block
__block int a = 0;
void(^block1)(void) = ^(void)
{
    //在block内部不能直接修改局部变量的值,
    如果想修改必须声明成__block类型的变量
    a ++;
    NSLog(@"block1 %d",a);
};

block1();//执?block

//2.有参?返回值
void(^block2)(int age, NSString *string) = ^(int
                                             age, NSString *string)
{
    NSLog(@"age = %d, text = %@", age, string);
};

block2(20,@"?明");

//3.?参有返回值类型的block
NSString *(^block3)(void) = ^(void)
{
    return @"?参有返回值";
};

NSLog(@"block3 = %@“,block3());

//4.有参有返回值类型的block
NSString *(^block4)(NSString *text) =
^(NSString *string)
{
    return [string
            stringByAppendingString:@"有返回值"];
};

NSLog(@"block4 %@", block4(@"有参"));

__block int a = 6;
    void (^testBlock)() = ^{
        NSLog(@"%d",a);//Block内部可以访问局部变量的值
       
        a = 9;//Block内部如果想修改外界局部变量的值,必须对变量进行__block修饰
       
        count = 101;//Block内部可以直接修改全局变量的值,也可以直接访问全局变量的值
    };
    testBlock();

NSLog(@"a = %d, count = %d",a, count);

  • 使?场景类似协议传值,都是解决从后?个页?往前?个页?传值问题

Block传值的两种方式:

  • ?式?: 使?block属性实现回调传值

#warning 第?步
//在第?个???声明block属性
typedef void (^BaDa)(NSString *);

typedef void (^FuFu)(UIColor *);

//Block声明成属性,必须使?copy,retain?效
@property (nonatomic, copy) FuFu fufu;

@property (nonatomic, copy) BaDa bada;

#warning 第?步
//在第?个???执?block回调,将所要传的值传给第?个??
- (void)back {
    //执行Block
    if (self.bada != nil) {
        self.bada(self.textField.text);
    }
    if (self.fufu != nil) {
        self.fufu(self.view.backgroundColor);
    }
    [self.navigationController popViewControllerAnimated:YES];

}

#warning 第三步
//在第?个???,实现block

- (void)push {

SecondViewController *secondVC = [[SecondViewController alloc] init];
    secondVC.bada = ^(NSString *str) {
        self.label.text = str;
    };
    secondVC.fufu = ^(UIColor *color) {
        self.view.backgroundColor = color;
    };
   
    [self.navigationController pushViewController:secondVC animated:YES];

[secondVC release];

}

#warning 第四步
//block内存管理
- (void)dealloc {

//释放Block有专门的方法

Block_release(_bada);
    Block_release(_fufu);
    [super dealloc];

}

  • ?式?: 在?法中定义block实现回调传值

#warning 第?步
//在AppTool.h中重定义void(^)(NSString *string)类型的别名为AppToolBlock
typedef void(^AppToolBlock)(NSString *string);

#warning 第?步

//声明?法,在?法中封装block
-(void)sendNumber:(NSInteger )number andBlock:

(AppToolBlock)block;

#warning 第三步
//在AppTool.m实现?法,并执?block
-(void)sendNumber:(NSInteger )number andBlock:(AppToolBlock)block;
{
    NSString *string = [NSString stringWithFormat:@"%ld",number];
    block(string);

}

#warning 第四步
-(void)buttonAction:(UIButton *)button
{
    AppTool *appTool = [[AppTool alloc] init];
    //执??法,实现block并接收回传过来的string值
    [appTool sendNumber:10086 andBlock:^(NSString *string) {
        self.label.text = string;
    }];

}

四、Block内存管理

• 没有使?局部变量的block内存存储在全局区
void(^block)(void) = ^(void)
{
};
NSLog(@"block = %@“,block);

运?结果: block = <__NSGlobalBlock__: 0x107321360>

• block内部使?局部变量的时候内存存储在栈区
__block int a = 0;
void(^block)(void) = ^(void)
{
    a = 10;
};
NSLog(@"block = %@",block);

运?结果: block = <__NSStackBlock__: 0│7fff57a920c8>

  • 当block变量定义为属性的时候,必须使?copy修饰,retain ?效,即retain和assign会造成野指针问题.
  • 当对block进?copy操作的时候,此时block的内存区域为堆 区.
  • 当不使?block时需要使?Block_Release()进?销毁.
  • 注意:关于block内存管理上的三个区域,在arc和?arc下还是 有区别的

//block会造成self的引?计数+1

-(void)pushAction:(UIButton *)button
{
    self.FirstBlock([UIColor yellowColor]);
    NSLog(@"firstBlock === %@",self.FirstBlock);
}

运?结果:firstBlock === <__NSMallocBlock__: 0│7ff838d14b70>

-(void)dealloc
{
    Block_release(_FirstBlock);
    [super dealloc];

}

//block会造成self的引?计数+1,使?__block 修饰变量来解决block循环引?问题
SecondViewController *secondVC = [[SecondViewController alloc] init];
__block FirstViewController *firstVC = self;
secondVC.SecondBlock = ^(NSString *string){
    firstVC.label.text = string;
};
注意:
在?arc下使?__block修饰变量来防?循环引?

在arc下使?__week修饰变量来防?循环引?

时间: 2024-10-25 15:47:38

界面通信的相关文章

iOS基础-UINavigationController、界面通信

UINavigationController 导航控制器 是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器 导航控制器以栈的方式管理所控制的视图控制器,至少要有一个被管理的视图控制器,这个控制器我们称作导航控制器的根视图控制器 出栈和入栈pushViewController:animated:进入下一个视图控制器 popViewControllerAnimated:返回上一个视图控制器 popToviewContro

界面通信之属性传值、代理传值

界面通信有三种方法 1.属性传值 2.代理传值 3.blcok传值 先讲讲属性和传值和代理传值 //属性传值- (void)sendValue { SecondViewController *secondVC = [[SecondViewController alloc] init]; secondVC.string = _textField.text;//这句是属性传值的核心,在需要接收值的界面声明一个字符串属性接受值 secondVC.color = self.view.background

##DAY8 界面通信

##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面传值) 属性传值:可以自定义属性.也可使用控件.视图的自带属性 1.属性传值用于第一个界面向第二个页面传值 2.明确两者联系的桥梁,也就是触发跳转的地方 3.明确传输的值:类型是什么 4.在第二个视图控制器内部声明相对应类型的属性,来接收传输的值 5.在第二个界面使用传入的值 注意:属性在传值中如果

UINavigationController 、界面通信

一.UINavigationController 二.定制UINavigationBar 三.界面间通信 一.UINavigationController 导航控制器,是iOS中最常用的多视图控制器之一,它用来管多个视图控制器.导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. UINavigationController继承于UIViewController,以栈的方式管理所控制的视图控制器, 至少要有一个被管理的视图控制器,这个控制器我们称作,导航控制器的根视图控制器. 任

UI_08 UINavigationController、界面通信

?.UINavigationController UINavigationController:导航控制器,是iOS中最常?的多视图控制器 之?,它?来管理多个视图控制器. 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. UINavigationController继承于UIViewController,以栈的?式管理所 控制的视图控制器,?少要有?个被管理的视图控制器,这个控制器 我们称作,导航控制器的根视图控制器. 任何继承?UIViewController的类(多态)

UI基础:UINavigationController、界面通信

UINavigationControlle UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器.也称为多视图控制器. 导航控制器可以认为是管理控制器的控制器,主要管理有层级关系的控制器. 创建: UINavigationController继承于UIViewController,以栈的形式管理所 控制的视图控制器,至少要有1个被管理的视图控制器,这个控制器 我们称作,导航控制器的根视图控制器. 任何继承于UIViewContro

iOSDay27之界面通信

1. 属性传值(前面的界面给后面传值) 第一步: 在 SecondViewController.h 文件里定义一个存放传过来值的变量 contents 1 #import <UIKit/UIKit.h> 2 3 @interface SecondViewController : UIViewController 4 5 // 第一步:声明属性,用于存放传过来的值 6 @property (nonatomic, copy) NSString *contents; 7 8 @end 第二步: 在

iOS学习之界面通信

一.属性传值 在SecondViewController.h里 #import <UIKit/UIKit.h> @interface SecondViewController : UIViewController // 第一步:声明属性,用来存放上一页传过来的数据 @property (nonatomic, copy) NSString *contents; @end 在RootViewController.m里 - (void)loginAction { SecondViewControll

界面通信之block传值

block传值有两种方式 ?式?: 使?block属性实现回调传值 ?式?: 在?法中定义block实现回调传值 方式一比较便于理解而且常用,下面介绍方式一是如何传值的 使用block属性传值和代理传值的步骤基本上是一样的 typedef void(^BaDa)(NSString *, UIColor *); @interface SecondViewController : UIViewController @property (nonatomic, retain) UITextField *