iOS-個人整理13 - 界面間傳值:屬性傳值---代理傳值---block傳值---單例傳值

一、屬性傳值

從前向后

假設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];  
                           
    [secondVC release];  
}  

第三步:在B中使用content的屬性給相應的控件賦值

@implementation 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,assign)id <協議名>delegate;

#pragma mark 這里是B的.h  
  
#import <UIKit/UIKit.h>  
  
@protocol CustomTabBarDelegate <NSObject>  
  
//把btn的tag傳出去的方法  
-(void)selectedIndexWithTag:(NSInteger)tag;  
  
@end  
  
@interface CustomTabBarView : UIView  
  
//聲明一個協議屬性delegate  
@property (nonatomic,assign)id <CustomTabBarDelegate>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(@"selectIndexWithTag該方法沒有實現");  
    }  

第四步:在A的.m中,在push到B界面的push方法之前,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:(NSInteger)tag  
{  
    self.selectedIndex = tag;  
}  

三、block傳值

這里就不具體講block是怎么回事了,這是OC的基礎內容。
block就是一塊代碼片段,類似于函數但是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的返回方法中  
  
nbsp;//調用block方法  
   self.passValueTag(sender.tag - 1000);  

第三步:
在A的.m中創建B的實例的地方,為B的block屬性賦值,也就是說,寫好這個block中的內容,類似于給B的某一個屬性賦初值

//設置block內容  
   customView.passValueTag = ^(NSInteger tag)  
   {  
       self.selectedIndex = tag;  
   };  
     

這里只有三步,比代理的方法簡單了不少

下面是實現效果
第一頁有個Label,在第二頁的輸入框輸入文字,就可以顯示在第一頁的label上,實現了從后向前的傳值


沒有引用局部變量的block內存存儲在全局區

沒有引用局部變量的block內存存儲在全局區

引用了局部變量的block內存存儲在棧區

當對block進行copy操作的時候blcok的內存在堆區

block的循環引用問題
當block是self的一個屬性的時候
self.circleBlock = ^() { my_self.navigationItem.title = @"asd"; };
會導致self的引用計數+1,最終導致循環引用
在arc下使用__weak修飾變量防止循環引用
在非arc下使用__block修飾變量防止循環引用

四、單例傳值

單例傳值基本思路是創建一個SingleTon類,里面定義一個要傳的值的屬性,再聲明一個share類方法,在類方法中用static定義類的實例變量,讓它只初始化一次。
這樣凡是導入這個SingleTon類的文件都可以通過share方法聲明一個實例變量,從變量中拿到它的屬性,這個屬性是地址唯一的,也就是說,大家拿到的都一樣,一處變化,任何位置拿到的這個值都變化。
創建SingleTon類
SingleTon.h

#import <Foundation/Foundation.h>  
  
@interface SingleTon : NSObject  
//傳值的具體屬性  
@property (nonatomic,retain)NSString *passValue;  
  
//一般單例是類方法來創建  
+(SingleTon*)sharedSingleTon;  
  
@end  
SingleTon.m
#import "SingleTon.h"  
  
@implementation SingleTon  
  
+(SingleTon *)sharedSingleTon  
{  
    //static 只賦值一次  
    static SingleTon *singleTon = nil;  
      
    //線程鎖,保證同時只有一個線程訪問  
    @synchronized(self) {  
        if (!singleTon) {  
            singleTon = [[SingleTon alloc]init];  
        }  
    }    
    return singleTon;  
}  
  
@end  
//GCD方法創建單例  
  
+(XMPPTools *)sharedXMPPTool  
{  
    static XMPPTools *xmppTools = nil;  
      
    //GCD方式創建單例      
    static dispatch_once_t onceToker;  
    _dispatch_once(&onceToker, ^{  
        xmppTools = [[XMPPTools alloc]init];  
    });     
    return xmppTools;  
}  

這次把代碼貼全點
AppDelegate.h


#import "AppDelegate.h"  
#import "RootViewController.h"  
#import "SecondViewController.h"  
  
@interface AppDelegate ()  
  
@end  
  
@implementation AppDelegate  
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
    // Override point for customization after application launch.  
    self.window.backgroundColor = [UIColor whiteColor];  
    [self.window makeKeyAndVisible];  
      
    RootViewController *rootVC = [[RootViewController alloc]init];  
    //創建導航控制器  
    UINavigationController *naviagtionC = [[UINavigationController alloc]initWithRootViewController:rootVC];  
      
    self.window.rootViewController = naviagtionC;  
      
    return YES;  
}  

用的時候在兩個ViewController文件中導入SingleTon.h
RootViewController.m

#import "RootViewController.h"  
#import "SingleTon.h"  
#import "SecondViewController.h"  
  
@interface RootViewController ()<UITableViewDelegate,UITableViewDataSource>  
  
@property (nonatomic,retain)UITextField* myTextField;  
  
@end  
  
@implementation RootViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
      
    self.navigationItem.title = @"第一頁";  
  
      
    //添加UItextField  
    _myTextField = [[UITextField alloc]initWithFrame:CGRectMake((414-200)/2, 200, 200, 40)];  
    _myTextField.borderStyle = UITextBorderStyleLine;  
    _myTextField.placeholder = @"input";  
      
    //添加按鈕  
    UIButton *myBtn = [UIButton buttonWithType:UIButtonTypeSystem];  
    myBtn.frame = CGRectMake((414-100)/2, 300, 100, 100);  
    [myBtn setTitle:@"確定" forState:UIControlStateNormal];  
    myBtn.layer.cornerRadius = 50;  
    myBtn.layer.masksToBounds = YES;  
    myBtn.backgroundColor =  [UIColor colorWithRed:200/255.0 green:233/255.0 blue:160/255.0 alpha:1];  
    //添加按鈕方法  
    [myBtn addTarget:self action:@selector(jumpToSecondVC:) forControlEvents:UIControlEventTouchUpInside];  
      
    [self.view addSubview:myBtn];  
      
    [self.view addSubview:_myTextField];  
  
}  
//重復調用的方法,再返回時用單例的值給標題  
-(void)viewWillAppear:(BOOL)animated  
{  
    SingleTon *singleTon = [SingleTon sharedSingleTon];  
    if (singleTon.passValue.length) {  
        self.navigationItem.title = singleTon.passValue;  
    }  
      
}  
  
-(void)jumpToSecondVC:(UIButton*)sender  
{  
    NSLog(@"tap btn");  
    SingleTon *mySingleTon = [SingleTon sharedSingleTon];  
    //把輸入框的值給單例的屬性  
    mySingleTon.passValue = _myTextField.text;  
    SecondViewController *secondVC = [[SecondViewController alloc]init];  
    [self.navigationController pushViewController:secondVC animated:YES];  
}  

SecondViewController.m


#import "SecondViewController.h"  
#import "SingleTon.h"  
  
@interface SecondViewController ()  
  
@property (nonatomic,retain)UITextView *myTextView;//  
@property (nonatomic,retain)UITextField *testTextField;  
  
@end  
  
@implementation SecondViewController  
  
- (void)viewDidLoad {  
    [super viewDidLoad];  
      
    self.navigationItem.title = @"第二頁";  
  
    SingleTon *mySingleTon = [SingleTon sharedSingleTon];  
    self.navigationItem.title = mySingleTon.passValue;  
      
      
    _testTextField = [[UITextField alloc]initWithFrame:CGRectMake((414-200)/2, 300, 200, 40)];  
      
    [self.view addSubview:_testTextField];  
    _testTextField.placeholder = @"input";  
      
    mySingleTon.passValue = _testTextField.text;  
      
}  
//view即將消失時,也就是返回前,賦值給單例  
 -(void)viewWillDisappear:(BOOL)animated  
{  
     
    SingleTon *mySingleTon = [SingleTon sharedSingleTon];  
    mySingleTon.passValue = _myTextField.text;  
   
}  
6d166d224f4a20a4bf5d186d93529822730ed0dd.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,885評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,312評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,993評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,667評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,410評論 6 411
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,778評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,775評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,955評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,521評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,266評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,468評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,998評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,696評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,095評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,385評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,193評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,431評論 2 378

推薦閱讀更多精彩內容

  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,330評論 11 349
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,067評論 6 13
  • 1.OC里用到集合類是什么? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,393評論 0 3
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,733評論 18 399
  • 設計模式 1.delegate和notification什么區別,什么情況使用? 2.描述一下KVO和KVC。 K...
    丶逐漸閱讀 1,968評論 3 2