iOS传值方式总结

时间一长,尤其是在迭代或者维护一个框架成熟的应用的时候,很多基础的东西就会忘记。今天写了个带有block的方法,竟然用了老长时间。看来要总结一下,忘记的时候有个地方,可以翻一翻,看一看。

传值方式都有啥

  • 属性传值
  • 委托Delegate传值
  • 通知NSNotification传值
  • block传值
  • 单例传值
  • runtime动态绑定传值

-----------------------看涨图,放松下-----------------------


one.jpg

说到人生,不管谁都是业余新手啊。 任何人都是第一次参加,人生这种事没有什么专业老手。 by 伊坂幸太郎

1.属性传值

ViewController1页面跳转到ViewController2页面【包括push,或者模态跳转】

  • ViewController2的属性
#import <UIKit/UIKit.h>

@interface ViewController2 : UIViewController

@property (nonatomic, strong)NSString *titleStr;

@end
  • 如何传值,在ViewController1跳转的地方,以下代码
 ViewController2 *viewVc2 = [[ViewController2 alloc] init];
    viewVc2.titleStr = @"传给界面2的值";
    [self presentViewController:viewVc2 animated:YES completion:^{
        
    }];

2.委托Delegate传值

这种方法的使用情景不同于上面的正向传值,相反,当ViewController2消失的时候,它需要传值给ViewController1

写代理的步骤

  • 声明ViewController2的协议--protocol,以及协议方法
  • 在ViewController2的.h文件中声明ViewController2的代理
  • 在ViewController2要进行传值的地方,进行容错处理,即判断他的代理是否实现了自己的协议方法,若完成,就执行,进行传值。
    *在ViewController2的代理--ViewController1中,首先遵守ViewController2的协议,其次,实现ViewController2的协议方法
  • 上面的都完成了,就可以进行传值。
timg.jpg

注意不按这个套路出牌的,往往要吃很多亏。
慢慢长大了,却越来越觉得,这个世界到处都他妈的套路。
到底是我不懂这个世界,还是世界抛弃了我!!!!
我要回村里

下面的例子-----在ViewController2关闭的时候,改变ViewController1的背景颜色
  • 声明ViewController2的协议--protocol,以及协议方法,并且声明代理
#import <UIKit/UIKit.h>

@protocol ViewController2Delegate <NSObject>

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

@end

@interface ViewController2 : UIViewController

@property (nonatomic, assign)id <ViewController2Delegate>delegate1;

@end

  • 在ViewController2要进行传值的地方,进行容错处理,即判断他的代理是否实现了自己的协议方法,若完成,就执行,进行传值。
#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    close.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:close];
    
    [close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
    // Do any additional setup after loading the view.
    
}

- (void)closeClick {
    if ([self.delegate1 respondsToSelector:@selector(setViewController1BackColor:)]) {
        [self.delegate1 setViewController1BackColor:[UIColor redColor]];
    }
    
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];

}

  • 在ViewController2的代理--ViewController1中,首先遵守ViewController2的协议,其次,实现ViewController2的协议方法
#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController ()<ViewController2Delegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
     UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    btn.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:btn];
    
    [btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)test {
    [self push];
}


- (void)push {
    ViewController2 *viewVc2 = [[ViewController2 alloc] init];
    viewVc2.titleStr = @"传给界面2的值";
    viewVc2.delegate1 = self;
    [self presentViewController:viewVc2 animated:YES completion:^{
        
    }];
}

- (void)setViewController1BackColor:(UIColor *)color {
    self.view.backgroundColor = color;
}

@end

效果图如下

delegate.gif

???????????????????????????????
???????????????????????????????

@property (nonatomic, assign)id <ViewController2Delegate>delegate1;

这儿为什么用assign?????拜读一下下面文章,我也是这意思,哈哈
[点这儿] http://www.jianshu.com/p/398472616435

3.通知NSNotification传值

在ViewController1中,注册观察者,并在dealloc中,移除

#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationClick:) name:@"setViewController1BackColor" object:nil];
    
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    btn.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:btn];
    
    [btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
    
}

- (void)notificationClick:(NSNotification *)noti {
    NSDictionary *dic = noti.userInfo;
    self.view.backgroundColor = (UIColor *)dic[@"color"];
}

- (void)test {
    [self push];
}


- (void)push {
    ViewController2 *viewVc2 = [[ViewController2 alloc] init];
    viewVc2.titleStr = @"传给界面2的值";
    [self presentViewController:viewVc2 animated:YES completion:^{
        
    }];
}

- (void)setViewController1BackColor:(UIColor *)color {
    self.view.backgroundColor = color;
}

-(void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:self];
}

@end

在ViewController2中,点击close按钮,发送通知

#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    close.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:close];
    
    [close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
    // Do any additional setup after loading the view.
    
}

- (void)closeClick {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"setViewController1BackColor" object:self userInfo:@{@"color":[UIColor redColor]}];
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
   
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

效果图---与上边一样

4.block传值

block传值是通过block块进行

在ViewController2中定义block属性

//  ViewController2.h
//  JRMBubbleTutorial
//
//  Created by 周钦凯 on 16/11/1.
//  Copyright © 2016年 Caroline Harrison. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef void(^setViewController) (UIColor *color);
@interface ViewController2 : UIViewController

@property (nonatomic, strong)NSString *titleStr;
@property (nonatomic, copy)setViewController block;

@end

在ViewController2.m中利用block声明部分传值

#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    UIButton *close = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    close.backgroundColor = [UIColor purpleColor];
    [self.view addSubview:close];
    
    [close addTarget:self action:@selector(closeClick) forControlEvents:UIControlEventTouchUpInside];
    // Do any additional setup after loading the view.
    
}

- (void)closeClick {
    _block([UIColor redColor]);
    [self dismissViewControllerAnimated:YES completion:^{
        
    }];
}

在ViewController中,初始化ViewController2对象部分,实现属性block的实现部分,在代码块中实现改变ViewController1背景颜色的效果

#import "ViewController.h"
#import "ViewController2.h"



@interface ViewController ()


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
    btn.backgroundColor = [UIColor yellowColor];
    [self.view addSubview:btn];
    
    [btn addTarget:self action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
    
}



- (void)test {
    [self push];
}


- (void)push {
    ViewController2 *viewVc2 = [[ViewController2 alloc] init];
    viewVc2.titleStr = @"传给界面2的值";
    viewVc2.block = ^(UIColor *color) {
        self.view.backgroundColor = [UIColor redColor];
    };
    
    [self presentViewController:viewVc2 animated:YES completion:^{
        
    }];
}

- (void)setViewController1BackColor:(UIColor *)color {
    self.view.backgroundColor = color;
}

效果图依然如上

问题,block为什么用copy修饰
block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。   使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。
[详情](http://www.cnblogs.com/MasterPeng/p/5311911.html

learn.jpg

目过代码过千行,撸码如有神 -- °腐

5.单例传值

什么是单例??
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
1、书写步骤
1)、创建类方法,返回对象实例.以shared default current开头。2)、创建一个全局变量用来保存对象的引用3)、判断对象是否存在,若不存在,创建对象
[点击] http://www.jianshu.com/p/2bdec6f7ebe7

上面单例,为我们在全工程,提供了一个公共的对象,随时随地可以取到,可以算为一种传值方式。如果觉得不是,那看下面这个系统单例。

  • 存数据--- 全局
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:@"1" forKey:@"isAl"];
    [userDefaults synchronize];

  • 取数据--全局
[userDefaults objectForKey:@"isAl"];

5.runtime传值

有时候,在同一个类里,方法之间传值,我们可以采用runtime动态绑定的方法

动态绑定

// 第一个参数:给哪个对象添加关联 
// 第二个参数:关联的key,通过这个key获取 
// 第三个参数:关联的value 
// 第四个参数:关联的策略 
objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

动态取值

objc_getAssociatedObject(self, key);

差不多了!!!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容