iOS--開發中的六大傳值(OC中的常用傳值)

六大傳值--(屬性/代理/通知/KVO/KVC/Tag/單例/Block/全局)

先創建兩個ViewController:

1,先在Appdelegate.m里設置一個AViewController.m 為rootViewController,并創建一個BViewController

在AViewController.m中導入BViewController.h,,,創建一個SingleOne繼承于NSObject作為單例類

import "AViewController.h"

import "BViewController.h"

//單例

import "SingleOne.h"

//代理傳值,遵循協議Nextprotocol
@interface AViewController ()<UITextFieldDelegate,Nextprotocol>
{
BViewController *bView;
}

@end

@implementation AViewController

  • (void)viewDidLoad {
    [superviewDidLoad];

    self.title =@"AViewController";
    self.view.backgroundColor = [UIColorwhiteColor];

    //作一個跳轉button
    UIBarButtonItem *item = [[UIBarButtonItemalloc]initWithTitle:@"跳轉"style:UIBarButtonItemStylePlaintarget:selfaction:@selector(touchAction:)];
    self.navigationItem.rightBarButtonItem = item;

//聲明一個aTextFiled
UITextField *aTextField = [[UITextFieldalloc]initWithFrame:CGRectMake([UIScreenmainScreen].bounds.size.width/2-150, [UIScreenmainScreen].bounds.size.height/2-25,300, 30)];
aTextField.layer.borderWidth =2;
aTextField.layer.borderColor = [UIColorgrayColor].CGColor;
aTextField.layer.masksToBounds =YES;
aTextField.tag = 1000;
aTextField.delegate = self;
[self.viewaddSubview:aTextField];

// aTextField.text = @"李濤你個混蛋";

//反正是KVO時就一定要放在viewdidLoad這里,不會跳兩第二次時會報錯,說這個bView已經消亡了但還有人在監聽它
bView = [[BViewController alloc]init];

}

  • (BOOL)textFieldShouldReturn:(UITextField *)textField
    {
    [textField resignFirstResponder];
    return YES;

}

-(void)touchAction:(UIButton *)sender
{
//用tag傳值
UITextField *aTextFiled = (UITextField *)[self.viewviewWithTag:1000];
// NSLog(@"aTextFiled.text = %@",aTextFiled.text);
// BViewController *bView = [[BViewControlleralloc]init];

/*-------------------單例傳值:從A---->>B  ----------------------*/
    SingleOne *onlyOne = [SingleOneshareData];
//讓單例作為中介去接收A頁面要傳的值,
    onlyOne.value = aTextFiled.text;


/*-------------------block傳值:從B---->>A  -------------------*/
[bView setMblock:^(NSString *string){ //注意類型,也可以用id
    aTextFiled.text = string;
}];

bView.mblock = ^(id string){
    aTextFiled.text = string;
};


/*---------------------屬性傳值:從A--->>B  --------------------*/
bView.text1 = aTextFiled.text;




/*---------------------KVC傳值-------------------------*/
[bView setValue:aTextFiled.textforKey:@"_name"];
[bView setValue:aTextFiled.textforKey:bView.text1];   //或者



/*---------------------通知傳值 B--->>A ------------------------*/
//

如果是從A傳到B的話,這里寫發通知,B.m里要創建一個init方法,在里面寫監聽并在里面創建接收容器才能成功(因為程序先執行init方法再到viewDidLoad方法,當傳值過去時在init就開始監聽,如果這里沒有創建textField接收,那就傳不過去了,所以要在init里同時創建接收器(生命周期的問題));
//這里是從B到A:注冊監聽:從B傳到A話因為從A跳轉到B時已經創建好A了,所以
[[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(aAction:)name:@"amessage"object:nil];

/*---------------------代理傳值 B--->>A  -------------------*/
bView.delegate = self;   //設置代理

/---------------------KVO回傳值 B--->>A-------------------/
//注冊觀察者:如果用了KVO一定要把bView的初始化放在上面的viewDidLoad里
[bView addObserver:self forKeyPath:@"test1" options:NSKeyValueObservingOptionNew context:nil];
//把更改之后的值提供給觀察者的回調方法

[self.navigationControllerpushViewController:bView animated:YES];

}

pragma mark============代理傳值:實現協議方法==============

-(void)transferString:(NSString *)string
{
UITextField *aTextField = (UITextField *)[self.viewviewWithTag:1000];

aTextField.text = string;

}

pragma mark -----------通知回調方法實現--------------

-(void)aAction:(NSNotification *)sender
{
UITextField *aField = (UITextField *)[self.viewviewWithTag:1000];
aField.text = sender.userInfo[@"akey"];

}

pragma mark ------------- KVO回調 ------------------

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
UITextField *aTextField = (UITextField *)[self.view viewWithTag:1000];

//此處監聽鍵路徑key的值有沒有發生變化
if ([keyPath isEqualToString:@"text1"]) {  //如果觀察的對象是text1
    aTextField.text = bView.text1;
}

}

//移除通知的監聽者 和 KVO的觀察者(如果不移除,會變成野指針)
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"amessage" object:nil]; //移除通知監聽者

[bView removeObserver:self forKeyPath:@"text1"];   //移除KVO觀察者

}

  • (void)didReceiveMemoryWarning {
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

/*

pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    }
    */

@end

BVIewController.h里

//
// BViewController.h
// test傳值
//
// Created by ibokan on 16/3/16.
// Copyright ? 2016年譚其偉. All rights reserved.
//

import <UIKit/UIKit.h>

pragma mark ======Block傳值=========

typedef void(^TransferValue) (NSString *string);

pragma mark---------代理傳值-------------

//聲明一個協議
@protocol Nextprotocol <NSObject>
//協議里的方法(讓遵循該協議的類實現,自己不實現)
-(void)transferString:(NSString *)string;

@end

@interface BViewController : UIViewController
{
//KVC傳值需要有一個實例變量作為key
NSString *_name;
}

//把block作為屬性
@property(nonatomic,copy)TransferValue mblock;

//屬性傳值
@property(nonatomic,readwrite,strong)NSString *text1;

pragma mark---------代理傳值-------------

//有一個遵循協議的代理屬性
@property(nonatomic,readwrite,strong)id<Nextprotocol>delegate;

@end

BViewController.m里

//
// BViewController.m
// test傳值
//
// Created by ibokan on 16/3/16.
// Copyright ? 2016年譚其偉. All rights reserved.
//

import "BViewController.h"

//單例

import "SingleOne.h"

@interface BViewController ()<UITextFieldDelegate>
{
UITextField *bTextFiled;
}
@end

@implementation BViewController

  • (void)viewDidLoad {
    [superviewDidLoad];

    self.title =@"BViewController";

    self.view.backgroundColor = [UIColorredColor];

    //聲明一個返回button
    UIButton *aButton = [UIButtonbuttonWithType:UIButtonTypeCustom];
    aButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width/2-50,150, 100, 30);
    [aButton setTitleColor:[UIColorblackColor] forState:UIControlStateNormal];
    [aButton addTarget:selfaction:@selector(backAction:)forControlEvents:UIControlEventTouchUpInside];
    [aButton setTitle:@"返回"forState:UIControlStateNormal];
    [self.viewaddSubview:aButton];

//使用全局傳值:聲明一個bTextFiled
bTextFiled = [[UITextFieldalloc]initWithFrame:CGRectMake([UIScreenmainScreen].bounds.size.width/2-150, [UIScreen mainScreen].bounds.size.height/2-100,300, 30)];
bTextFiled.layer.borderColor = [UIColorblackColor].CGColor;
bTextFiled.layer.borderWidth =2;
//_btextFiled.delegate = self;
bTextFiled.text = [NSStringstring];  //相當于nil
bTextFiled.layer.masksToBounds =YES;
[self.viewaddSubview:bTextFiled];

pragma mark ------單例傳值接收:再間接傳給B頁面-----------------

bTextFiled.text = [SingleOneshareData].value;

pragma mark ++++++++++++屬性傳值++++++++++++++++

bTextFiled.text =self.text1;

//KVC傳值
self.text1 =_name;
bTextFiled.text =self.text1;

pragma mark ==============通知傳值:回傳=====================

//發送通知
[[NSNotificationCenterdefaultCenter] postNotificationName:@"amessage"object:selfuserInfo:@{@"akey":bTextFiled.text}];

}

-(void)backAction:(UIButton *)sender
{

/*-------------block傳值要寫在方法里----------------*/
_mblock(bTextFiled.text);
self.mblock(bTextFiled.text);



/*---------------代理傳值-------------------------*/
if (self.delegate && [self.delegateconformsToProtocol:@protocol(Nextprotocol)]) {
    [self.delegatetransferString:bTextFiled.text];
}



[self.navigationControllerpopViewControllerAnimated:YES];

}

  • (void)didReceiveMemoryWarning {
    [superdidReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
    }

/*

pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
    }
    */

@end

單例類:

SingleOne.h

// SingleOne.h
// test傳值
//
// Created by ibokan on 16/3/16.
// Copyright ? 2016年譚其偉. All rights reserved.
//

import <Foundation/Foundation.h>

@interface SingleOne : NSObject

//創建一個單例//如果在單線程里可以用nonatomic,如果在多線程里一定要用atomic,保證是只有一個在調用,不然在多線程里面如果多個方法調用修改單例類里的屬性時會沖突
@property(atomic,readwrite,strong)NSString *value;

//聲明一個類方法
+(SingleOne *)shareData;

@end

SingleOne.m里

//
// SingleOne.m
// test傳值
//
// Created by ibokan on 16/3/16.
// Copyright ? 2016年譚其偉. All rights reserved.
//

import "SingleOne.h"

//聲明一個表態實例對象,讓其為空
static SingleOne *onlyOne =nil;

@implementation SingleOne

//實現方法,判斷是否為空,是就創建一個全局實例給它
+(SingleOne *)shareData
{
if (onlyOne ==nil) {
onlyOne = [[SingleOnealloc]init];
}
returnonlyOne;
}

//避免alloc/new創建新的實例變量--->增加一個互斥鎖
+(id)allocWithZone:(struct_NSZone *)zone
{
@synchronized(self) {
if (onlyOne ==nil) {
onlyOne = [superallocWithZone:zone];
}
}
returnonlyOne;
}

//避免copy,需要實現NSCopying協議
-(id)copyWithZone:(NSZone *)zone
{

return self;

}

@end

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容