欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

详解iOS页面传值(顺传 逆传)

程序员文章站 2024-02-17 20:35:22
代理协议传值 顺传 假设a为第一个视图控制器,b为第二个视图控制器 在a中导入b的.h文件 场景:a向b传值 第一步:在b的.h中定义一个content属性...

代理协议传值

顺传

假设a为第一个视图控制器,b为第二个视图控制器

在a中导入b的.h文件

场景:a向b传值

第一步:在b的.h中定义一个content属性

@interface secondviewcontroller : uiviewcontroller
@property(nonatomic,copy)nsstring *contents;
@end

第二步:在点击a中的按钮方法里面给b的content属性赋值

- (void)buttonaction:(uibutton *)button
 {
 nslog(@"进入第二页");
 secondviewcontroller *secondvc = [secondviewcontroller alloc] init];
 secondvc.contents = self.label.text;
 [self.navigationcontroller pushviewcontroller:secondvc animated:yes];
 }

第三部:在b使用content的属性给相应的控件赋值

@implemention secondviewcontroller
- (void)viewdidload {
 [super viewdidload];
 self.view.backgroundcolor = [uicolor whitecolor];
 self.navigationitem.title = self.contents;
 }

逆传

代理传值使用在两个界面传值的之后,从后向前传值。

假设a为第一个视图控制器,b为第二个视图控制器

场景:b向a传值

第一步:首先在b的.h文件中声明协议和协议方法

第二步在b的.h中声明一个代理属性,这里主要注意用assign或weak修饰,weak和assign是一种非拥有关系的指针,通过这两种修饰符修饰的指针变量,都不会改变被引用的对象的引用计数。但是在一个对象被释放后,weak会自动将指针指向nil,而assign则不会。所以,用weak更安全些。

@property (nonatomic,weak)id<协议名>delegate;

#pragma mark 这里是b的.h
#import<uikit/uikit.h>
@protocol csutomtabbardelegate<nsobject>
// 把btn的tag传出去的方法
- (void)selectedindexwithtag:(nsinteger)tag;
@end
@interface customtabbarview : uiview
//声明一个代理属性delegate
@property (nonatomic,weak)id<csutomtabbardelegate>delegate;
@end

第三部:在b即将pop回前一个界面的时候,在pop方法的上一行使用协议方法传递数据[self.delegate 协议方法名:(参数,也就是要传回的数据)

#pragma mark 这里是b的.m
// 判断在制定的代理类中是否实现了该协议方法
// 确保执行时无此方法时不崩溃
if([self.delegate respondstoselector:@selector(selectedindexwithtag:)])
{
 // 执行代理方法
 [self.delegate selectedindexwithtag:(sender.tag - 1000)];
}
else
{
 nslog(@"协议中的方法没有实现");
}

在a的.m中,在push到b界面方法之前,b对象的初始化之后,指定a对象为b对象的代理(b对象).delegate = self此时会有黄色警告,因为没有准守协议

#pragma mark a的.m中
// 指定代理,b就是customview
customview .delegate = self;

第五步:在a的延展或者a的.h文件中导入协议名称<协议名称>

#pragma mark a的.m的延展里,a就是roottabbarcontroller
// 协议导入
@interface roottabbarcontroller () <customtabbardelegate>
@end

第六步:在a的.m中事项协议方法,取得参数中得知,呈现在当前界面上

#pragma mark a的.m
// 实现代理方法,这里就可以使用从b传来的值了
- (void)selectedindexwithtag:(nsingeter)tag
 {
  self.selectedindex = tag;
 }

使用block页面间传值

第一步:在b的.h中重定义一个block,用这个重定义的block类型声明一个类的属性这里要注意用copy修饰block属性

#pragma mark b的.h 
#import <uikit/uikit.h> 
// block传值 
// 重命名一个有参无返回值的block类型 
typedef void(^passvalue)(nsinteger tag); 
@interface customtabbarview : uiview 
 //用这个block类型定义一个属性 
@property (nonatomic,copy)passvalue passvaluetag; 
@end

第二步:在b的.m的返回方法中调用block的方法

#pragma mark b的.m的返回方法中 
//调用block方法 
self.passvaluetag(sender.tag - 1000);

第三步:在a的.m中创建b的实例的地方,为b的block属性赋值,也就是说,写好这个block中的内容,类似于给b的某一个属性赋初值

// 设置block内容 
 customview.passvaluetag = ^(nsinteger tag) 
 { 
  self.selectedindex = tag; 
 };

没有引用局部变量的block内存存储在全局区

引用了局部变量的block内存存储在栈区

当对block进行copy操作的时候block的内存存在堆区

block的循环引用问题

当block是self的一个属性的时候

self.circleblock = ^(){my_self.navigationitem.title = @"hello";};

会导致self的引用计数+1,最终导致循环引用

在arc下使用weak修饰变量防止循环引用

在非arc下使用block修饰变量防止循环引用

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持!