美文网首页
iOS的五种传值

iOS的五种传值

作者: 谁偷走了我爱吃的奶酪 | 来源:发表于2017-11-30 18:11 被阅读0次

前言

iOS常见的五种传值分别为属性传值,通知传值,代理传值,block传值,单例传值

属性传值

用于正向传值,简单,但对象之间得相关联
模拟一个场景, A->B(A传值B)
B.h文件定义一个变量


@interface lastViewController : UIViewController
@property(nonatomic,strong)NSString * str;
@end

A.m文件跳转并传值

    lastViewController * last = [[lastViewController alloc]init];
    // [[NSNotificationCenter defaultCenter]postNotificationName:nsnotificationName object:nil];
    last.str = self.textField.text;
    [self.navigationController pushViewController:last animated:YES];
}

通知传值

不需要编写多少代码,实现比较简单,对象可以不关联,跨层传值,一对多(发送一个通知,订阅该通知的都会得到相应,是同步的),通知使用过多显得太乱,不好调试
模拟一个场景 : C->B && C->A
订阅通知,尽量在delloc里移除该通知,注册通知和移除通知是成双成对(iOS8之前),这里附上两个链接
iOS尽量不要在viewWillDisappear:方法中移除通知
iOS 9 NSNotificationCenter移除问题
A订阅通知

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(value:) name:nsnotificationName object:nil];
}

A销毁移除通知

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

或者移除单个通知

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

B和A控制器一样,最后在C发送通知

NSDictionary * dict = @{@"key":self.textField.text};
[[NSNotificationCenter defaultCenter]postNotificationName:nsnotificationName object:nil userInfo:dict];

记得先订阅,在发送再能接收到通知的

代理传值

代理传值一对一,可以定义多个方法,但定义代码太过繁琐
逆向传值 B->A
B.h : 声明协议,定义代理执行的方法,并定义一个该协议的属性

@protocol lastViewControllerDelegate<NSObject>
//方法可实现的
@optional
//方法必须实现
//@required
-(void)pushViewcontroler:(NSString *)str;
@end
@interface lastViewController : UIViewController
@property(nonatomic,weak)id<lastViewControllerDelegate>delagate;
@end

B.m

//设置视图将要消失时.通过代理传值
//判断代理是否存在,并且设置代理能够响应代理方法时,才执行代理方法
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    if (self.delagate && [self.delagate respondsToSelector:@selector(pushViewcontroler:)]) {
        [self.delagate pushViewcontroler:@"哈哈"];
    }
}

A.m 服从协议,设置代理,并实现协议的方法

//服从协议
@interface ViewController ()<lastViewControllerDelegate>
@end

- (IBAction)push:(id)sender {
    lastViewController * last = [[lastViewController alloc]init];
    //设置代理
    last.delagate = self;
    [self.navigationController pushViewController:last animated:YES];
}
//实现协议方法
-(void)pushViewcontroler:(NSString *)str{
    self.textField.text = str;
}

block传值

代码简洁,反向传值,模拟场景 B->A
B.h声明block属性

@property(nonatomic,strong)void(^Myblcok)(NSString * str);

B.m调用该block

self.Myblcok([self.showLabel.text substringToIndex:<#(NSUInteger)#>]);

A.m 接收该block

 lastViewController * last = [[lastViewController alloc]init];
    last.Myblcok = ^(NSString *str) {
        self.textField.text = str;
    };
    last.str = self.textField.text;
    [self.navigationController pushViewController:last animated:YES];

block简单定义使用可以看看这篇 : iOS之轻松上手block(上)

单例传值

  1. 创建一个单例
@interface model : NSObject
@property(nonatomic,strong)NSString * str;
//暴露一个方法,供外界访问
+(model *)del;
@end
static  model * del = nil;
@implementation model
+(instancetype)allocWithZone:(struct _NSZone *)zone{
    return [model del];
}
+(model *)del{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        del = [[super allocWithZone:nil]init];
    });
    return del;
}
//在通过拷贝的时候创建对象时,会调用到-(id)copyWithZone:(NSZone *)zone,-(id)mutableCopyWithZone:(NSZone *)zone方法。因此,可以重写这些方法,让创建的对象唯一。
+ (id)copyWithZone:(struct _NSZone *)zone{
    return [model del];
}
+ (id)mutableCopyWithZone:(struct _NSZone *)zone{
    return [model del];
}
@end

2.A中为单例的属性赋值

- (void)viewDidLoad {
    [super viewDidLoad];
    model * del = [model del];
    del.str = @"我是单例的属性";
}

3.B中获取单例属性

- (void)viewDidLoad {
    [super viewDidLoad];
    model * del = [model del];
    self.showLabel.text = del.str;
}

了解单例的创建可以看看 :iOS中的单例模式

感言

这次是我对iOS最开始学习的内容回顾,自己的理解,有不对的望指出,谢谢

相关文章

网友评论

      本文标题:iOS的五种传值

      本文链接:https://www.haomeiwen.com/subject/atzybxtx.html