您的位置:首页 > 移动开发 > IOS开发

iOS开发之 各种传值总结

2015-09-15 17:44 459 查看
一、自定义构造函数和属性传值
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、写上代理方法 等待被执行
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: