代理協議傳值
順傳
假設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修飾變量防止循環引用
以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持本站!