淺談iOS常用的幾種傳值方式

swcfsfy發表於2017-12-13

1.屬性傳值

UIViewController *B = [UIViewController new];
    
B.title = @"B的標題";
    
[A.navigationController pushViewController:B animated:YES];

複製程式碼

通常用於正向傳值,適用於A和B相互具有一定關聯性。不能用於隔頁面傳值。而且,需要傳值的屬性不能是私有屬性,也就是說在.h中宣告出來的屬性才可以傳值。

2.Block傳值

使用場景: 常用於回撥,簡單的說就是B有一個按鈕,當按鈕被點選時把點選事件傳傳給A,並傳一個字串"B被點了"。

//首先在B控制器中宣告一個block,引數是一個字串
@property (nonatomic,copy) void(^block)(NSString *title);

//同樣在B控制器,在按鈕點選觸發的方法裡執行block
- (void)buttonClick:(UIButton *)sender
{
    self.block(@"B被點了");
}

//現在回到A控制器,在推出B的時候給B的block賦值,簡單的說,就是在收到B的訊息時,想要做什麼事
 BController *B = [BController new];
    
    B.block = ^(NSString *title) {
        
        //do someThing
        A.title = title;
        
    };
    
    [A.navigationController pushViewController:B animated:YES];

複製程式碼

同樣的Block在這裡作為屬性存在,同屬性傳值一樣,需要兩個控制器間具有一定關聯性。不能跨頁面傳值。 如果一定要跨,就要像接力賽一樣,A傳給B,B傳給C這樣

3.代理傳值

代理傳值和block傳值相似,都是將事件分發出去。但是與block的不同在於,代理具有鬆耦合性,誰想處理事件成為代理即可。

//首先,在B裡定義個協議並宣告一個代理
@protocol B_ButtonClickDelegate <NSObject>

- (void)B_ButtonIsClicked:(NSString *)message;

@end

@interface BController : UIViewController

@property (nonatomic,assign) id<B_ButtonClickDelegate>delegate;

@end

//B控制器,點選事件發生時讓代理去執行代理方法
- (void)buttonClick:(UIButton *)sender
{
    [self.delegate B_ButtonIsClicked:@"B的按鈕被點了誰來管管"];
}

//推出B之前,讓A成為B的代理
BController *B = [BController new];
    
B.delegate = A;
    
[A.navigationController pushViewController:B animated:YES];

//最後A遵守協議並實現對應代理方法
@interface AController ()<B_ButtonClickDelegate>

- (void)B_ButtonIsClicked:(NSString *)message
{
    self.title = message;
}

複製程式碼

4.通知中心傳值

上面說的代理屬於一對一的關係,就好像一夫一妻制。你有需求只能找你的代理(你老婆)。而通知中心屬於一對多的,就像村頭的喇叭一喊,全村人都能聽到。 而在實際開發中,常見用到的通知地方就是更換主題。在某個控制器發生事件,其他已存在的控制器作出響應。這裡注意一點,是已存在

//在需要處理事件的控制器的初始化方法裡訂閱通知,注意,一定是先訂閱
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dealAction:) name:@"B的按鈕被點了大家響應下" object:nil];

//收到通知後執行什麼事?實現**dealAction:**即可
- (void)dealAction:(NSNotification *)sender
{
    //這裡的object就是發出通知時附帶
    NSLog(@"%@",sender.object);
    //列印結果--"哈薩克"
}

//在B控制器需要處理事件的時候發出通知
- (void)buttonClick:(UIButton *)sender
{
    [[NSNotificationCenter defaultCenter] postNotificationName:@"B的按鈕被點了大家響應下" object:@[@"哈薩克"]];
}

複製程式碼

5.單例傳值

iOS系統中常間的單例模式莫過於UIApplication、 NSNotificationCenter、 NSUserDefaults 如何建立單例這裡不做說明,以NSUserDefaults為例說下具體使用


//以鍵值對的形式存值到NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:@"哈薩克" forKey:@"亞索"];

//從NSUserDefaults取出
NSString *value = [[NSUserDefaults standardUserDefaults] objectForKey:@"亞索"];
    
NSLog(@"%@",value); //列印結果--"哈薩克"

複製程式碼

6.資料庫傳值

資料庫無非在於開啟資料庫、建表以及基於資料庫表的增刪改查操作

這裡有一個唐巧大大的FMDB的demo自行學習吧demo點這裡

7.NSFileManager

跟資料庫類似,只是將資料寫成檔案儲存在沙盒中。 需要注意的: 1.檔案路徑是否正確 2.不能儲存複雜物件

相關篇幅還是有點長度的,這裡推薦個連結詳細瞭解點這裡

8.全域性變數傳值

在某個檔案的.m檔案建立一個全域性變數,其他檔案只要引用該變數,即可對該變數值進行修改和使用。需要注意,變數名要保證全域性唯一。

//建立全域性變數
NSString *message;

@implementation AController

//引用全域性變數
extern NSString *message;

@implementation BController

//使用和修改
extern NSString *message;

@implementation BController

- (void)buttonClick:(UIButton *)sender
{
    self.title = message;
    
    message = @"我愛你中國";
}
複製程式碼

相關文章