順傳
假設(shè)A為第一個視圖控制器,B為第二個視圖控制器
在A中導入B的.h文件
場景:A向B傳值
第一步:在B的.h中定義一個content屬性
@interfaceSecondViewController: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 {? ? [superviewDidLoad];self.view.backgroundColor = [UIColorwhiteColor];self.navigationItem.title =self.contents; }
逆?zhèn)?/p>
代理傳值使用在兩個界面?zhèn)髦档闹蟾П剩瑥暮笙蚯皞髦怠?/p>
假設(shè)A為第一個視圖控制器,B為第二個視圖控制器
場景:B向A傳值
第一步:首先在B的.h文件中聲明協(xié)議和協(xié)議方法
第二步:在B的.h中聲明一個代理屬性陷猫,這里主要注意用assign或weak修飾切端,weak和assign是一種非擁有關(guān)系的指針,通過這兩種修飾符修飾的指針變量珍逸,都不會改變被引用的對象的引用計數(shù)吵取。但是在一個對象被釋放后禽额,weak會自動將指針指向nil,而assign則不會皮官。所以脯倒,用weak更安全些。
@property (nonatomic,weak)id<協(xié)議名>delegate臣疑;
#pragma mark 這里是B的.h#import@protocolCsutomTabBarDelegate// 把btn的tag傳出去的方法- (void)selectedIndexWithTag:(NSInteger)tag;@end@interfaceCustomTabBarView:UIView//聲明一個代理屬性delegate@property(nonatomic,weak)iddelegate;@end
第三部:在B即將POP回前一個界面的時候盔憨,在pop方法的上一行使用協(xié)議方法傳遞數(shù)據(jù)[self.delegate 協(xié)議方法名:(參數(shù),也就是要傳回的數(shù)據(jù))
#pragma mark 這里是B的.m// 判斷在制定的代理類中是否實現(xiàn)了該協(xié)議方法// 確保執(zhí)行時無此方法時不崩潰if([self.delegate respondsToSelector:@selector(selectedIndexWithTag:)]){// 執(zhí)行代理方法[self.delegate selectedIndexWithTag:(sender.tag -1000)];}else{NSLog(@"協(xié)議中的方法沒有實現(xiàn)");}
在A的.m中讯沈,在push到B界面方法之前郁岩,B對象的初始化之后,指定A對象為B對象的代理(B對象).delegate = self此時會有黃色警告缺狠,因為沒有準守協(xié)議
#pragmamark A的.m中// 指定代理问慎,B就是customViewcustomView .delegate=self;
第五步:在A的延展或者A的.h文件中導入?yún)f(xié)議名稱<協(xié)議名稱>
#pragma mark A的.m的延展里,A就是RootTabBarController// 協(xié)議導入@interfaceRootTabBarController() @end
第六步:在A的.m中事項協(xié)議方法挤茄,取得參數(shù)中得知如叼,呈現(xiàn)在當前界面上
#pragma mark A的.m// 實現(xiàn)代理方法,這里就可以使用從B傳來的值了- (void)selectedIndexWithTag:(NSIngeter)tag {self.selectedIndex = tag; }
使用Block頁面間傳值
第一步:在B的.h中重定義一個block穷劈,用這個重定義的block類型聲明一個類的屬性這里要注意用copy修飾block屬性
#pragma mark B的.h #import// block傳值? // 重命名一個有參無返回值的block類型? typedefvoid(^passValue)(NSIntegertag);@interfaceCustomTabBarView:UIView//用這個block類型定義一個屬性? @property(nonatomic,copy)passValue passValueTag;@end
第二步:在B的.m的返回方法中調(diào)用block的方法
#pragmamark B的.m的返回方法中? //調(diào)用block方法self.passValueTag(sender.tag -1000);
第三步:在A的.m中創(chuàng)建B的實例的地方笼恰,為B的block屬性賦值踊沸,也就是說,寫好這個block中的內(nèi)容社证,類似于給B的某一個屬性賦初值
// 設(shè)置block內(nèi)容? customView.passValueTag = ^(NSIntegertag)? ? {self.selectedIndex = tag;? ? };
沒有引用局部變量的Block內(nèi)存存儲在全局區(qū)
引用了局部變量的Block內(nèi)存存儲在棧區(qū)
當對Block進行copy操作的時候Block的內(nèi)存存在堆區(qū)
Block的循環(huán)引用問題
當Block是self的一個屬性的時候
self.circleBlock = ^(){my_self.navigationItem.title = @"Hello";};
會導致self的引用計數(shù)+1逼龟,最終導致循環(huán)引用
在ARC下使用weak修飾變量防止循環(huán)引用
在非ARC下使用block修飾變量防止循環(huán)引用