iOS 常用傳值方式

weixin_34075551發表於2017-12-22

總結 iOS 日常開發中的幾種常用傳值方式:

  1. 正向傳值
  2. 代理傳值
  3. block傳值
  4. 通知傳值
  5. 單例

文章程式碼:https://github.com/mortal-master/BWTransferValueDemo


1. 正向傳值

  • 使用場景:介面 A 跳轉介面 B 的同時,向介面 B 傳遞值,即上級向下級傳遞
  • 步驟:
    1. 在介面 B 的 .h 檔案中公開宣告一個屬性

      @interface ViewC1 : UIViewController
      
      //正向傳值 1
      @property (nonatomic, copy) NSString *value_1;
      
      @end
      
    2. 匯入介面 B 的標頭檔案,並使用 B 建立出一個物件,對屬性進行賦值

      ViewC1 *VC1 = [[ViewC1 alloc] init];
      VC1.value_1 = @"我是正向傳值";
      [self.navigationController pushViewController:VC1 animated:YES];
      

2. 代理傳值

  • 使用場景:介面 A 跳轉介面 B ,介面 B 返回介面 A 時傳結果給 A,即下級向上級傳遞
  • 步驟:
    1. 在介面 B 標頭檔案中定義協議

      @protocol ViewC2Delegate <NSObject>
      
      - (void)changeMainVCBackgroundColor:(UIColor *)color;
      @end
      
    2. 在介面 B 標頭檔案中定義代理屬性

      @interface ViewC2 : UIViewController
      
      @property (nonatomic, weak) id<ViewC2Delegate> delegate;
      @end
      
    3. 在介面 B 的 .m 中合適位置呼叫代理方法

      // 3.呼叫代理方法 <需先進行檢測>
      if ([self.delegate respondsToSelector:@selector(changeMainVCBackgroundColor:)]) {
          [self.delegate changeMainVCBackgroundColor:[UIColor greenColor]];
      }
      
    4. 在介面 A 中設定代理

    5. 在介面 A 中遵守協議

      @interface ViewController ()<ViewC2Delegate>
      @end
      
      ViewC2 *VC2 = [[ViewC2 alloc] init];
      VC2.delegate = self;
      [self.navigationController pushViewController:VC2 animated:YES];
      
    6. 實現代理協議中的方法

      - (void)changeMainVCBackgroundColor:(UIColor *)color {
          
          self.view.backgroundColor = color;
      }
      

3. block傳值

  • 使用場景:類似代理,當協議中的方法只有一個,可以使用 block,此時可以不用寫協議,相當於簡化的代理
  • 步驟:
    1. 在傳送者標頭檔案中定義 block 屬性

      @interface ViewC3 : UIViewController
      
      @property (nonatomic, copy) void (^changeMainVCBgColor)(UIColor *color);
      
      @end
      
    2. 在傳送者 .m 檔案合適位置呼叫 block

      //呼叫block
      if (self.changeMainVCBgColor) {
          self.changeMainVCBgColor([UIColor redColor]);
      }
      
    3. 在接收者中實現具體操作

      ViewC3 *VC3 = [[ViewC3 alloc] init];
      VC3.changeMainVCBgColor = ^(UIColor *color) {
          self.view.backgroundColor = color;
      };
      [self.navigationController pushViewController:VC3 animated:YES];
      

4. 通知傳值

  • 使用場景:代理一般適用於上下級之間,若是多級結構時會相當麻煩,使用通知沒有級別結構限制
  • 步驟:
    1. 在傳送者中釋出通知

      //1.釋出通知
      NSDictionary *dict = @{@"color":[UIColor grayColor]};
      [[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeMainBgColor" object:@"VC42" userInfo:dict];
      
    2. 在接收者中註冊通知

      //2.一般在 viewDidLoad 中註冊通知
      //通知名稱需一致
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"viewDidLoad" object:@"VC42"];
      
    3. 在接收者中實現通知具體操作

      - (void)changeColor:(NSNotification *)noti {
          
          NSDictionary *dict = noti.userInfo;
          self.view.backgroundColor = [dict valueForKeyPath:@"color"];
      }
      
    4. 在接收者中登出通知

      - (void)dealloc {
          
          [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ChangeMainBgColor" object:@"VC42"];
      }
      

5. 單例傳值

  • 使用場景:多次建立僅有唯一一個,隨用隨取
  • 步驟:
    1. 建立單例類,宣告需要傳遞的屬性

      @interface Person : NSObject
      
      interfaceSingleton(PersonName);
      
      @property (nonatomic, copy) NSString *name;
      
      @end
      
    2. 例項化一個物件,對物件的屬性進行賦值

      Person *person = [[Person alloc] init];
      person.name = @"單例賦值的名字";
      
    3. 在需要用到的地方例項化一個物件,取出屬性值

      Person *person = [[Person alloc] init];
      NSLog(@"取出單例賦值:%@", person.name);
      

      PS: 建立單例類請檢視我之前的文章《iOS 單例模式簡析》


個人部落格:https://mortal-master.github.io

相關文章