iOS开发之 各种传值总结

一、自定义构造函数和属性传值

1、首先在需要值的类中自定义构造函数并在.h文件中声明

//自定义构造函数传值

//.m文件中

- (instancetype)initWithList:(NSArray *)list{

    if (self = [super init]) {

        myList = list;

}

    return self;

}

//.h文件

- (instancetype)initWithList:(NSArray *)list;

//在哪个类里面 需要 数据 就可以使用属性 **向上一个页面** 要值

//正向传值

//使用一个对象 里面的属性、方法...的时候 必须有这个对象存在

@property (nonatomic, copy) NSString *titleName;

//属性传值

1>在声明文件中声明一个属性

2>在实现文件中将属性赋值作为标题

//.m文件

self.title = self.titleName;

2、在传值的类中初始化被传值的对象,在初始化时将值赋给被传值初始化对象。

//Next_ViewController需要一个值 从ViewController传到 Next_ViewController

//只要alloc init 就会初始化 一个新的对象

//这个对象 就跟 之前的对象 不是同一个对象 (之前存在的旧对象里面的数据 就会被清空 (它里面 没有被赋值))

  

1>当不同类型(或者类)响应同一个方法时,可以通过 isKindOfClass 判断这个对象 属于哪种类型(哪个类)

//判断手势

if([sender isKindOfClass:[UITapGestureRecognizer class]] == YES){}

2>初始化一个数组,并将需要传得值放在初始化的数组

NSArray *list = @[@"自定义", @"构造函数", @“传值"];

Next_ViewController *next = [[Next_ViewController alloc] initWithList:list];

//属性传值

next.titleName = @"传值";

3> 手势里面有一个 状态属性 可以通过 手势触发的状态 判断 手势触发的时间段

        if (sender.state == UIGestureRecognizerStateBegan) {

            Next_ViewController *next = [[Next_ViewController alloc] initWithList:@[@"属性传值", @"属性"]];

            next.titleName = @"正向传值";   

        }

二、KVC与KVO传值

1、KVC(键值编码)传值

1>KVC主要通过”key”来进行传值。通过找到属性或者全局变量的值

2>“key”是属性或者全局变量的名字

2、KVO(键值观察者)传值

1>KVO主要通过观察“属性”的状态的变化做出相应地操作。比如从后台数据库获取数据,界面首次初始化时,只有数据发生变化界面才会发生改变。

2>KVO首先要注册一个监视中心

//[Model sharManger]创建一个单例

[[Model sharManger] addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];

//模拟从后台数据库获取数据

[NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(updateTitle) userInfo:nil repeats:YES];

//获取数据

- (void)updateTitle{

     NSArray *list = @[@"K", @"V", @"O"];

    [Model sharManger].title = list[arc4random()%list.count];

}

3>观察数据是否发生变化

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

    if ([keyPath isEqualToString:@"title"]) {

        //记录 所有发生的改变

        [all addObject:change[@"old"]];

        label.text = change[@"new"]

        for (NSString *s in all) {

            NSLog(@"%@", s);

        }

    }


4>移除观察者

[[Model sharManger] removeObserver:self forKeyPath:@"title"];

三、单例传值

1>新建一个类继承NSObject






#import "Model.h"

static Model *model = nil;

@implementation Model

+(instancetype)sharManger{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        model = [[Model alloc] init];

    });

    return model;

}

@end  

}

2>声明两个属性

//标题

@property (nonatomic, copy) NSString *title;

//图片

@property (nonatomic, retain) UIImage *image;

3>在ViewController.m中导入单例类并给属性赋初值

[Model sharManger].title = @"风景";

[Model sharManger].image = [UIImage imageNamed:@“begin"];

4>在Next_ViewController类中

UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.view.frame];

    imageView.image = [Model sharManger].image;

    [self.view addSubview:imageView];  

    [Model sharManger].image = [UIImage imageNamed:@"bg"];

5>因为单例只初始化一次,所以在第一次图片传过去之后,之后图片将会一直是@“bg"


四、通知传值

1、通知是一对多的传值,通知传值首先要有观察者。

2、首先注册一个消息中心(在这里模拟请求服务器获取用户账号信息)

 1>建一个继承NSObject的HTTPResquestManager类

//在实现中实现以下方法

+ (void)getRequest{

    NSDictionary *dic = @{@"username":@"通知传值", @"password":@"123456"};

      sleep(5);

    [[NSNotificationCenter defaultCenter] postNotificationName:@"didResponse" object:nil userInfo:dic];

}

2>在观察者对象中接收通知

(1)- (instancetype)init

{

    self = [super init];

    if (self) {

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadDataMeassage:) name:@"didResponse" object:nil];

    }

    return self;

}

(2)在reloadDataMeassage方法中实现

- (void)reloadDataMeassage:(NSNotification *)not {

    label.text = [NSString stringWithFormat:@"%@\n%@", not.userInfo[@"userName"], not.userInfo[@"password"]];

}

3>移除观察者

  [[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:@"didResponse"];


五、Block(闭包)传值(block目的:用于反向传值)

1、局部变量

1>参数声明

返回值类型(^闭包的名字)(参数列表)

2>实现

闭包的名字 =  ^(参数列表){code}

3>调用

闭包的名字();

示例:

声明

void (^block)(int age, NSString *name);

实现

//如果想修改block外部的变量值 需要添加__block修饰

//__block int age;

block = ^(int age, NSString *name){

//代码实现

//age = 10;

NSLog(@"%d %@", age, name);

}

调用

block(20, @“小明”);


2、全局变量

1>在延展或.h中声明一个block全局变量

void (^imageNameBlock)(NSString *imageName);

2>在需要实现Block的方法中实现

***** 由于Block定义全局变量会循环引用 所以需要将该类设置成弱变量

__weak ViewController *vc = self;

__block UIImage *image = nil;

    imageNameBlock = ^(NSString *imageName){

        image = [UIImage imageNamed:imageName];

        vc.view.backgroundColor = [UIColor colorWithPatternImage:image];

    };

3>调用

imageNameBlock(@"logo");

4>为了避免重复初始化控件,需要将控件写在Block实现的外面


3、属性传值

1>在Next_ViewController.h文件中声明一个属性

@property (nonatomic, copy) void (^block)(NSString *title);

2>在Next_ViewController.m文件中,在返回上一个页面时,同时通过Block把这个页面的值传到上一个页面

self.block(@“Block属性传值”);

3>在初始化Next_ViewController的地方

next.block = ^(NSString *title){

NSLog(@“%@”, title);

}

4、方法传值

1>在Next_ViewController.h文件中声明一个方法

- (void)passValue:(void^(NSString *))block;

2>在Next_ViewController.m文件中实现方法

  • (void)passValue:(void^(NSString *))block{

      block(@“方法传值”);

}

3>在初始化Next_ViewController的地方调用此方法

[next passValue:^(NSString * title){

 NSLog(@“Block方法传值”);

}];


六、代理传值

代理:又叫委托 自己不能去办的事 委托给别人去办

1、声明代理方法(不要在@interface里面 声明代理方法)

//协议名字一般是类名+delegate

2、声明代理的属性 (可以通过这个属性找到  代理方法)

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

//声明代理的属性 用assign 分配栈里面

//id<NextDelegate>  代理的类型 尖括号里面是代理的名字

3、什么时候需要触发这个代理方法

//   respondsToSelector 判断一个方法 是否可以响应 返回值是一个BOOL值

4、通过协议的属性 调用代理的方法 (委托)

5、导入协议

@interface ViewController ()<NextDelegate>

6、在初始化有代理方法的对象地方 挂上代理

 7、写上代理方法 等待被执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值