常用的传值方法

目录

1.属性传值(正向)
2.block传值(反向)
3.通知传值(反向)
4.协议传值(反向)
5.单例传值

1.属性传值(正向)

这样就是正向的属性传值

2.block传值(反向)

思路:

1.首先,创建两个视图控制器,在第一个视图控制器中创建一个UILabel和一个UIButton,其中UILabel是为了显示第二个视图控制器传过来的字符串,UIButton是为了push到第二个界面
2.第二个界面的只有一个UITextField,是为了输入文字,当输入文字,并且返回第一个界面的时候,当第二个视图将要消失的时候,就将第二个界面上TextFiled中的文字传给第一个界面,并且显示在UILabel上

Demo:

效果:

补充:block相关知识点

http://www.jianshu.com/p/f4fa7aeb2035
http://www.jianshu.com/p/2aad46e3ea95

1.使用block时什么情况会发生引用循环,如何解决?

一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。
解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。
id weak weakSelf = self; 或者 weak __typeof(&*self)weakSelf = self该方法可以设置宏
id __block weakSelf = self;
或者将其中一方强制制空 xxx = nil。
检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具 FBRetainCycleDetector

block使用注意点:

3.通知传值(反向)

Demo1:

效果:

Demo2:(带数据)

VC1:
1.发送通知(传一个数据模型)
OrderListModel *nextModel = [self getNeedModel];//获取下一个要接的乘客
OrderViewModel *orderViewModel = [[OrderViewModel alloc] initWithOrderModel:nextModel];
//通知订单面板刷新
[[NSNotificationCenter defaultCenter] postNotificationName:@"GaodeNaviUpdateMapNaviPopupView" object:nil userInfo:@{@"orderViewModel":orderViewModel}];

VC2:
1.接收通知
- (void)viewDidLoad {
    [super viewDidLoad];
    //导航中更换终点导航刷新订单面板
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(gaodeNaviUpdateMapNaviPopupView:) name:@"GaodeNaviUpdateMapNaviPopupView" object:nil];
}

2.通知回调方法
//通知回调方法-高德导航中改变终点刷新订单面板
- (void)gaodeNaviUpdateMapNaviPopupView:(NSNotification *)sender {
    NSDictionary *dic = sender.userInfo;
    OrderViewModel *orderViewModel = dic[@"orderViewModel"];
    [orderViewModel refreshPrice];
    self.mapNavigationPopupView.orderViewModel = orderViewModel;//更新数据
}

3.移除通知
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
VC1:
1.发送通知(传一个数据)
[[NSNotificationCenter defaultCenter]postNotificationName:@"BBXListMapMergeNotification" object:nil userInfo:@{@"index":[NSString stringWithFormat:@"%ld",(long)i]}];

VC2:
1.接收通知
//任务列表-接送地图标题按钮点击的通知回调
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(BBXListMapMergeNotificationAction:) name:@"BBXListMapMergeNotification" object:nil];

2.通知回调方法
//任务列表-接送地图标题按钮点击的通知回调
- (void)BBXListMapMergeNotificationAction:(NSNotification *)sender {
    NSDictionary *dic  = sender.userInfo;
    NSString *index = dic[@"index"];
    if ([index isEqualToString:@"1"]) {
        self.currentTag = -1;
        [self refreshEvent:NO];//网络请求,刷新界面
        self.tipsLabel.hidden = YES;
        NSArray *tempArray = [NSArray arrayWithArray:self.orderArray];
        for (OrderListModel *orderModel in tempArray) {
            //有系统空单,移除系统空单数据,显示系统空单提示
            if (orderModel.order_origin.intValue == 999) {
                self.tipsLabel.hidden = NO;
                self.isHaveEmptyOrder = YES;
            }
        }
    }
}

//其他
//各界面弹框点详情到任务列表通知回调
- (void)BBXListMapMergeNotificationSwitchAction:(NSNotification *)sender {
    NSDictionary *dic  = sender.userInfo;
    NSString *index = dic[@"index"];
    if ([index isEqualToString:@"0"]) {
        NSArray *vcs = [_titleScrollView subviews];
        for (id view in vcs) {
            if ([view isKindOfClass:[UIButton class]]) {
                UIButton *btn = view;
                if (btn.tag == index.intValue) {
                    [self titleClick:btn];
                }
            }
        }
    }
}

3.移除通知
- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

Demo3:(通知的其他快捷写法 - 可当前VC发通知再收通知)

首页VC发送通知
首页VC接收通知
通知回调方法
补充:通知相关知识点

NSNotification:

这个类可以理解为一个消息对象,其中有三个成员变量;observer是观察者(一般在控制器中是self),它监测通知中心是否有消息发送的那个对象

  • name:这个成员变量是这个消息对象的唯一标识,用于辨别消息对象,必须与需要发送通知的名字一致,否则通知无法到达
  • object:这个成员变量定义一个对象,可以理解为针对某一个对象的消息;是通知关联的对象,即谁发送的通知(看情况,有时传的值很多,可以通过模型过渡...);也就是监听哪个对象发出的通知,如果使用"nil"值,代表监听所有通知
  • userInfo:这个成员变量是一个字典,可以用其来进行传值;也就是传递的附加信息(通知的内容)

NSNotificationCenter:

通信的特点是:为单例模式,可以实现一对多通信,每个应用程序都会有一个默认的通知中心;通知是观察者(observer)模式的一种,结构为:发布者->通知中心->接受者;
基本的使用过程:首先在需要接受数据的对象(或者控制器)注册通知,在需要发布通信的对象中上传通知

移除通知方法:

  • 移除通知需要注意的坑:

了解:在了解控制器的生命周期之后,我们都知道viewWillAppear:方法是在控制器的view将要显示的时候调用的,而viewWillDisappear:方法是在控制器的view将要隐藏的时候调用。很多时候我们根据自身需要将相关代码逻辑添加到这两个方法中。

  • 小结:

1、iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法。

2、在做手势和通知等一系列操作之时要分情况考虑:若通知和手势是与UI相关的,如监听UITextField键盘的显示和隐藏通知等应该在viewWillAppear:方法中添加通知,在viewWillDisappear:方法中移除通知;而与UI无关的通知和手势,像自定义通知等,应该在viewDidLoad等一次性方法中添加,在dealloc方法中释放。

3、在viewWillAppear:、viewWillDisappear:、viewDidAppear:、viewDidDisappear:等类似于这种会多次调用的系统方法中添加代码时,一定要多考虑业务逻辑,以免出现不必要的麻烦。

相关详细讲解链接:http://www.jianshu.com/p/ea2aadef413d

注意点:

1.接受者和发布者的通知名字必须一致
2.接受者的对象中注册使用完后应该移除通知,一般在dealloc中移除
3.通知可以用于传值,也可以用于其他地方;通知比较优雅,耦合性低

4.协议传值(反向)

Demo:

效果:

5.单例传值

Demo:

单例类:

.h文件
#import <Foundation/Foundation.h>

@interface Datahandle : NSObject

@property (nonatomic, strong) NSString *passVolud;

+(instancetype)sharedHandle;// 单例方法

@end
.m文件
#import "Datahandle.h"

@implementation Datahandle

// 1.重写init初始化方法(使用抛出异常的方式不让调用)
-(instancetype)init {
    
    @throw [NSException exceptionWithName:@"Datahandle" reason:@"不允许使用" userInfo:nil];
    return self;
}

// 2.废弃了系统的init方法,所以自己写一个私有的init方法(重新实现初始化)
-(instancetype)initPrivate {
    
    if (self = [super init]) {
        
    }
    return  self;
}

// 3.单例实现方法(系统线程加锁方式)
+(instancetype)sharedHandle {
    
    static Datahandle *datahandle = nil;// 用static修饰,这个方法只走一次
    
    @synchronized (self) {// 同步保护(互斥锁,保证线程安全)
        
        if (!datahandle) {
            
            datahandle = [[Datahandle alloc]initPrivate];// 用重新写的私有初始化
        }
    }
    return datahandle;
}

// 方法二(传统创建方式)
//+(instancetype)sharedHandle{
//
//    static Datahandle *datahandle = nil;
//    
//    if (!datahandle){
//        
//        datahandle = [[Datahandle alloc] init];
//    }
//    return datahandle;
//}

// 方法三 (线程方式--最优)
//+(instancetype)sharedHandle {
//    
//    static Datahandle *datahandle = nil;
//    static dispatch_once_t onceToken; //给单例加了一个线程锁
//    
//    dispatch_once(&onceToken, ^{
//        
//        datahandle = [[Datahandle alloc] init];
//    });
//    return datahandle;
//}

@end

效果:

单例相关知识点

1.简介

就是一个实例,单例是全局都可以使用的唯一的一个类,相当于一个全局变量,它提供了对类的对象所提供的资源的全局访问点。因此需要用一种只允许生成对象类的唯一实例的机制;
作用:可以保证的程序运行过程,一个类只有一个示例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源(就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个))

2.单例实现思路

• 首先必须创建一个全局实例,通常存放在一个全局变量中,此全局变量设置为nil

• 提供工厂方法对该全局实例进行访问,检查该变量是否为nil,如果nil就创建一个新的实例,最后返回全局实例

• 全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,所以需要重写该方法,防止通过标准的alloc方式创建新的实例

• 为了防止通过copy方法得到新的实例,需要实现-copyWithZone方法

• 只需在此方法中返回本身对象即可,引用计数也不需要进行改变,因为单例模式下的对象是不允许销毁的,所以也就不用保留

• 因为全局实例不允许释放,所以retain,release,autorelease方法均需重写

注意:类只能有一个实例,并且必须从一个为人数值的访问点对其访问;这个唯一的实例只能通过子类化进行拓展,并且拓展的对象不会破坏客户端代码

3.常见的系统单例

UIApplication(应用程序实例)
NSNotificationCenter(通知)
NSFileManager(文件管理):
NSUserDefaults(应用程序设置):
UIScreen
NSApplication
NSFontManager
NSDocumentController
NSHelpManager
NSNull
NSProcessInfo
NSScriptExecutionContext

4.使用场景

单例模式应用的场景一般发现在以下条件下:
1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
简单说就是:整个程序共用一份资源时(我们只需要对这份资源初始化一次)可以使用单例;例如:
1.设置单例类访问应用的配置信息
2.用户的个人信息登陆后用nsuserdefaults 存储,对登录类进一步采用单例封装方便全局访问
3.封装一个单例对应用多处对同一本地数据库进行操作

http://blog.csdn.net/tanyujing/article/details/14160941

参考文章:http://blog.csdn.net/blueboyhi/article/details/51074372

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

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,321评论 8 265
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,089评论 1 32
  • OC语言基础 1.类与对象 类方法 OC的类方法只有2种:静态方法和实例方法两种 在OC中,只要方法声明在@int...
    奇异果好补阅读 4,250评论 0 11
  • 一直都喜欢书,但真正喜欢读书是上了大学之后。每一天,每一年都有书相陪伴,那真是最好的日子。 17年寒假开始就一直在...
    神秘嘉宾HT阅读 271评论 11 2
  • 昨天下午无事儿子拿出水墨笔写字,我们俩你一个字我一个字心情愉快的聊着写着。 很高兴儿子对毛笔字感兴趣,他跟我说过几...
    Lucy刘阅读 312评论 0 0