1. 属性传值(前面的界面给后面传值)

 第一步: 在 SecondViewController.h 文件里定义一个存放传过来值的变量 contents

 #import <UIKit/UIKit.h>

 @interface SecondViewController : UIViewController

 // 第一步:声明属性,用于存放传过来的值
@property (nonatomic, copy) NSString *contents; @end

 第二步: 在 FirstViewController 的按钮点击方法里给 SecondViewController 的 contents 属性赋值

 - (void)loginButtonClick:(UIButton *)sender
{
// 创建对象
SecondViewController *secondVC = [[SecondViewController alloc] init]; // 第二步:进行赋值
secondVC.contents = self.rootView.userTextField.text; // 导航控制器push栈中
[self.navigationController pushViewController:secondVC animated:YES];
}

 第三步: 在 SecondViewController 将传过来的值显示, 使用 contents 属性给 nameLabel 赋值(在 viewDidLoad 中)

// 第三步:显示内容
self.nameLabel.text = self.contents;

2. 协议传值(后面的界面给前面传值)

 第一步: 声明协议(在委托方(SecondViewController)的 .h 文件中声明)

 #import <UIKit/UIKit.h>

 #warning 第一步:在SecondViewController.h里声明协议
@protocol SecondViewControllerDelegate<NSObject> // 声明协议方法
- (void)passValueWithString:(NSString *)textString; @end @interface SecondViewController : UIViewController @end

 第二步: 声明代理人(在委托方(SecondViewController)的 .h 文件中声明代理人, 代理人是一个属性)

 @interface SecondViewController : UIViewController

 #warning 第二步:声明代理人

 // 代理的语义设置使用assign, 防止循环引用
@property (nonatomic, assign) id <SecondViewControllerDelegate> secondDelegate; @end

声明属性时的语义必须是 assign , 使用 retain , copy 会导致循环引用问题

 第三步: 执行协议方法(委托方(SecondViewController)在点击事件中使用代理属性调用代理的传值方法)

 // 实现点击事件方法(实现代理从后往前传值)
- (void)submitButtonClick:(UIButton *)sender
{
// 1.把输入的内容传到第一页 #warning 第三步:使用代理调用代理的传值方法
// [self.secondDelegate passValueWithString:self.eatTextField.text]; // 判断如果代理实现了方法进行调用(安全判断,当没有方法实现时不会导致程序崩溃)
if ([self.secondDelegate respondsToSelector:@selector(passValueWithString:)]) {
[self.secondDelegate passValueWithString:self.eatTextField.text];
} // 2.跳回到第一页
[self.navigationController popViewControllerAnimated:YES];
}

 第四步: 签订协议(代理人(FirstViewController)遵守协议)

 #warning 第四步:遵守代理协议
@interface FirstViewController ()<SecondViewControllerDelegate> @property (nonatomic, strong) UILabel *myLabel; @end

 第五步: 指定代理人(在代理人(FirstViewController) 跳转到委托方的点击事件方法中指定)

 // 代理人的点击事件方法(跳转到委托方)
- (void)rightBarClick:(UIBarButtonItem *)sender
{
// 1.创建视图控制器对象
SecondViewController *secondVC = [[SecondViewController alloc] init]; #warning 第五步:设置代理人
// 指定当前对象为代理人
secondVC.secondDelegate = self; // 2.push跳转
[self.navigationController pushViewController:secondVC animated:YES];
}

 第六步: 实现协议方法(代理人(FirstViewController)实现代理方法, 并接收传过来的值显示)

 #warning 第六步:实现代理方法,并接收传过来的值
- (void)passValueWithString:(NSString *)textString
{
// 将传过来的值显示
self.myLabel.text = textString;
}

3. Block传值

 1> 回顾Block

 2> Block注意事项

  在 controller 中定义 Block , 实现 Block 的时候, 如果 Block 里面需要使用当前控制器对象,不可以直接使用 self , 否则会引起循环引用

  解决办法:

   ① 使用 __block 修饰变量防止循环引用(MRC)

   ② 使用 __weak 修饰变量防止循环引用(ARC)

     // 使用__weak修饰防止循环引用
// __weak SecondViewController *secodVC = self; // 一般写法 // typeof(...) 得到括号中的类型
__weak typeof(self) secodVC = self; // 装逼写法 self.block = ^void () {
NSLog(@"这事block的实现"); secodVC.view.backgroundColor = [UIColor grayColor];
};

  typeof(...) 得到括号中的类型

 3> Block传值的两种方式

  方式一: 使用Block属性实现回调传值

  方式二: 在方法中定义Block实现回调传值

 4> Block属性传值

  第一步: 在传值方(SecondViewController)定义 Block 属性

 #import <UIKit/UIKit.h>

 @interface SecondViewController : UIViewController

 #warning 第一步:定义Block属性
@property (nonatomic, copy) void(^secondBlock)(NSString *); @end

  第二步: 在接值方(FirstViewController) 跳转到委托方的点击事件实现方法中 实现Block, 即Block回调

 // 跳转点击事件实现方法
- (void)barClick:(UIBarButtonItem *)sender
{
SecondViewController *secondVC = [[SecondViewController alloc] init]; #warning 第二步 实现Block
// Block回调
secondVC.secondBlock = ^void (NSString *string) {
// 得到Block回传的string,并赋值给myLabel
self.myLabel.text = string;
}; [self.navigationController pushViewController:secondVC animated:YES];
}

  第三步: 在传值方(SecondViewController)的返回点击事件中, 调用Block实现传值

 // 实现方法 进行Block传值
- (void)submitButtonClick:(UIButton *)sender
{
// 1.Block传值 #warning 第三步 Block传值, 调用Block
self.secondBlock(self.textField.text); // 2.返回第一页
[self.navigationController popViewControllerAnimated:YES];
}

 5> 在方法中定义Block传值

 6> Block存储域

  ① 没有使用局部变量的 Block 内存存储在全局区

  ② 使用局部变量的 Block 内存存储在 栈区

  ③ 当 Block 变量定义为属性的时候, 必须使用 copy 修饰, retain无效, 即 retain 和 assign 会造成野指针问题

  当对 Block 进行 copy 操作的时候, 此时 Block 的内存区域为 堆区

  当不使用 Block 时需要使用 Block_Release() 进行销毁

iOSDay27之界面通信的更多相关文章

  1. ##DAY8 界面通信

    ##DAY8 界面通信 注意:延展中写的东西只能在类内使用 #pragma mark ———————属性传值—————————— (第一个页面往第二个页面传值) 一.属性传值:(第一个页面往第二个页面 ...

  2. UI:UINavigationController、界面通信

    IOS中实现对控制器的管理的控制器有:UINavigationController 和 UITableBarController 两个控制器.下面是主要学习前者. 参考 ⼀.UINavigationC ...

  3. iOS学习之界面通信

    一.属性传值 在SecondViewController.h里 #import <UIKit/UIKit.h> @interface SecondViewController : UIVi ...

  4. UI基础:UINavigationController、界面通信

    UINavigationControlle UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,它用来管理多个视图控制器.也称为多视图控制器. 导航控制器可以 ...

  5. 界面通信之block传值

    block传值有两种方式 ⽅式⼀: 使⽤block属性实现回调传值 ⽅式⼆: 在⽅法中定义block实现回调传值 方式一比较便于理解而且常用,下面介绍方式一是如何传值的 使用block属性传值和代理传 ...

  6. 1 TCP/IP通信

    重点参考长链接http://blog.csdn.net/fengyuzhengfan/article/details/38830115 http://blog.csdn.net/Jsagacity/a ...

  7. IOS开发官方文档随笔

    马上着手开发IOS应用程序 创建第一个单视图应用 ###main 方法 int main(int argc, char * argv[]) { @autoreleasepool { return UI ...

  8. 【ASP.NET】UCenter实现多站点同步登录退出

    利用UCenter实现discuz论坛和应用网站同步登录和退出功能 测试环境:Discuz! X3.2.UCenter 1.6..Net Framework 4.0 进入Discuz 后台的UCent ...

  9. Android按键添加和处理的方案

    Android按键添加和处理的方案  版本号 说明 作者 日期  1.0  Android按键添加和处理的方案 Sky Wang  2013/06/18        需求:Android机器上有个W ...

随机推荐

  1. Mysql 基于BinaryLog的复制

    .Mysql Master将更新[Update]和变化[Change]作为事件[events]写入Binary log.Mysql slaves 被配置为读取Binary log from maste ...

  2. NYOJ题目1082买新书了

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsoAAAI5CAIAAAA38ougAAAgAElEQVR4nO3dPVLjStsG4G8T5CyE2A

  3. spring刚开始学习搭建

    下载的软件包地址: http://repo.springsource.org/libs-release-local/org/springframework/spring 用maven进行快速开始: h ...

  4. hud 1019最小公倍数

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1019 思路:头两个数先求,再用所求的数与后面的一个数求,依次类推 #include<stdlib ...

  5. sql server 的cpu使用率过高的分析

    有哪些SQL语句会导致CPU过高? 1.编译和重编译 编译是 Sql Server 为指令生成执行计划的过程.Sql Server 要分析指令要做的事情,分析它所要访问的表格结构,也就是生成执行计划的 ...

  6. 数据结构和算法 – 9.二叉树和二叉查找树

      9.1.树的定义   9.2.二叉树 人们把每个节点最多拥有不超过两个子节点的树定义为二叉树.由于限制子节点的数量为 2,人们可以为插入数据.删除数据.以及在二叉树中查找数据编写有效的程序了. 在 ...

  7. Linux下pipe使用注意事项

    转自:http://blog.yufeng.info/archives/1485 Linux下的pipe使用非常广泛, shell本身就大量用pipe来粘合生产者和消费者的. 我们的服务器程序通常会用 ...

  8. POJ2778 DNA Sequence(AC自动机 矩阵)

    先使用AC自动机求得状态转移关系,再建立矩阵,mat[i][j]表示一步可从i到j且i,j节点均非终止字符的方案数,则此矩阵的n次方表示n步从i,到j的方法数. #include<cstdio& ...

  9. PHPCMS 实现上一篇下一篇的几种方法

    1第一种 <p>上一篇:{get sql = "select contentid,catid,url,titlee from phpcms_content where conte ...

  10. 一种快速刷新richedit中内嵌动画的方法的实现

    在IM中使用动画表情是一种非常有趣的方式,然而选择一种合适的方式来实现却并不容易. 一般来说,除了自己去实现一个富文本控件,目前主要的解决方案有3种: 1.使用浏览器做容器. 2.使用QT提供的Ric ...