ios中反向传值得几种方法

#pragma mark - 反向传值

1.代理

//主动方(第二个界面):1.创建协议及协议方法 2.设置一个代理属性 3.判断代理是否存在以及协议方法时候存在,然后再传值

//被动方:1.遵守协议 2.设置代理 3. 实现代理方法

@protocol ShowTextDelegate


@required

-(void)showText:(NSString *)text;

@optional

-(UIColor *)showTextOne:(NSString *)text;


@end


@interface SecodViewController : UIViewController


@property (nonatomic,assign)id delegate;


@end


//调用代理方法

//判断代理存在,且代理方法有响应

if (_delegate && [_delegate respondsToSelector:@selector(showText:)]) {

    UIColor *color =[_delegate showTextOne:textField.text];

    self.view.backgroundColor = color;

}


@interface RootViewController ()

//建立代理关系

svc.delegate = self;

//实现代理方法

-(UIColor *)showTextOne:(NSString *)text

{

    // 找到显示文字的label

    UILabel *label = (id)[self.view viewWithTag:10];

    label.text = text;

    return [UIColor greenColor];

}


//主动方

1.@property (nonatomic ,assign)id delegate;

2.[self.delegate setValue.btn.currentTitle forKey:@"viewCtrTitle"];

//被动方

1.@property (nonatomic,copy) NSString *viewCtrTitle;

2.svc.delegate = self;


3.self.navigationitem.title = viewCtrTitle;


2.block

@property (nonatomic,copy)void(^block)(NSString *text);

//2.SecodViewController要传递文字,它是需要声明block的一方

//3.SecodViewController它声明,它调用 (这样才能传过去一个数,才叫反向传值)

//4.声明一个属性,指向要调用的block


/*

 1.驱动方声明一个block属性 驱动方调用block,执行block中得代码

 2.被动方要具体实现block<驱动的block属性应该指向被动方实现的block>


 */

if (_block) {

    

    _block(textField.text);

}


//1.实现显示文字的功能,也就是它需要完成block的实现部分 这是第一个控制器的内容


SecodViewController *svc = [[SecodViewController alloc]init];


UILabel *label = (id)[self.view viewWithTag:10];


void(^aBlock)(NSString *text) = ^(NSString *text){

    label.text = text;

};


//声明的block指向实现的block

svc.block = aBlock;


#pragma mark - block的基本使用 只有调用block才会实现block中的代码

传入方声明block调用block,接收方实现block对传过来的值进行使用

#warining 1.声明block  2.调用block 3.实现block


@implementation RootViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    //1.block的声明

    

    //声明一个名字为blockNameblock变量

    //-(void)funcName:(BOOL)value

    

    void(^blockName)(BOOL value,NSString *str); (这句话blockName是名字,其余的是类型)

    //2.block赋值

    blockName = ^(BOOL va1,NSString * str1){     (这是给block赋值)

        NSLog(@"%d,%@",va1,str1);

    };

    //也可以把这一步和上一步合起来写,就是声明并且赋值

    void(^blockName)(BOOL value,NSString *str) = ^(BOOL va1,NSString * str1){     (这是给block赋值)

        NSLog(@"%d,%@",va1,str1);

    };


    blockName(YES,@"调用block");                   (这是调用block)

    //声明一个带返回值的block,并给它赋值

    

    __unsafe_unretained RootViewController *rvc =self;

    NSString *(^block2)(UIColor * color) =^(UIColor * colorValue){

        

        rvc.view.backgroundColor = colorValue;

        return@"用来返回的字符串";

        

    };

    

    NSString *str = block2([UIColor greenColor]);

    NSLog(@"block返回的字符串====%@",str);

    

    //3:block作为参数

    

    void(^useBlock)(BOOL value) = ^(BOOL value)

    {

        if (value ==YES) {

            

            NSLog(@"作为参数的block");

        }

    };

    

    [self useAblock:useBlock];

    /*

     [self useAblock:^(BOOL value) {

     if (value == YES) {

     

     NSLog(@"作为参数的block");

     }

     }];

     */

    -(void)useAblock:(void(^)(BOOL value))block

    {

        if (block) {

            NSLog(@"block");

            //如果作为参数的block存在,就调用block

            block(YES);

        }

    }

    //4.block作为返回值

    void(^returnAblock)(BOOL value) = [self returnAblock];

    if (returnAblock) {

        //如果返回的block有值就调用block

        // 调用block

        returnAblock(YES);

    }

    

}


//作为返回值

-(void(^)(BOOL value))returnAblock

{

    return ^(BOOL value){

        

        NSLog(@"作为返回值的block");

    };

}


-(void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear:animated];

    [self funcName:YES];

}

//函数的实现部分,不调用是不会执行函数中得代码的,调用才执行

-(void)funcName:(BOOL)value

{

    NSLog(@"调用函数");

}


#pragma mark - block的本质

需要注意防止循环引用,使用__weak关键词修饰

void test5();


int main(int argc,const char * argv[])

{

    test5();

    return0;

}


int num = 10;

void test5()

{

    void (^block)() = ^{

        // block内部能够一直引用全局变量

        NSLog(@"----num=%d", num);

    };

    

    num = 20;

    

    block();

}


void test4()

{

    staticint age = 10;

    void (^block)() = ^{

        // block内部能够一直引用被static修饰的变量

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test3()

{

    __blockint age = 10;

    void (^block)() = ^{

        // block内部能够一直引用被__block修饰的变量

        

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test2()

{

    int age =10;

    void (^block)() = ^{

        // 普通的局部变量,block内部只会引用它初始的值(block定义那一刻),不能跟踪它的改变

        //因为block不知道这个变量什么时候被销毁,所以直接把变量的值放到那个位置,不管以后变量的死活了,但是全局变量,被static修饰的变量,被_block修饰的变量可以一直引用,就是可以跟踪变量的变化

        NSLog(@"----age=%d", age);

    };

    

    age = 20;

    

    block();

}


void test()

{

    int age =10;

    void (^block)() = ^{

        // ----age=10

        NSLog(@"----age=%d", age);

    };

    block();

}


#pragma mark - block 传值

//2.block

@property (nonatomic, copy)void(^block)(NSString *text);

//2.SecodViewController要传递文字,它是需要声明block的一方

//3.SecodViewController它声明,它调用 (这样才能传过去一个数,才叫反向传值)

//4.声明一个属性,指向要调用的block


/*

 1.驱动方声明一个block属性 驱动方调用block,执行block中得代码

 2.被动方要具体实现block<驱动的block属性应该指向被动方实现的block>

 

 */

if (_block) {

    

    _block(textField.text);

}

//下面这代码在第一个控制器里面

//1.实现显示文字的功能,也就是它需要完成block的实现部分


SecodViewController *svc = [[SecodViewController alloc]init];


UILabel *label = (id)[self.view viewWithTag:10];


void(^aBlock)(NSString *text) = ^(NSString *text){

    label.text = text;

};


//声明的block指向实现的block

svc.block = aBlock;


3.通知

//   创建一个通知


//第一种:创建通知的方法

//A :携带对象

//1.通知的名字

//2.  通知携带的对象

//3.通知携带的信息

/*

 NSNotification *notify = [[NSNotification alloc]initWithName:@"ShowText" object:textField userInfo:nil];

 */

//    B:携带信息

//

//    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:textField.text forKey:@"text"];

//    NSNotification *notify1 = [[NSNotification alloc]initWithName:@"showtext" object:nil userInfo:infoDict];


//获取通知中心

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

//    [nc postNotification:notify];

//    [nc postNotification:notify1];


//第二种,创建并发送一个携带对象的通知

[nc postNotificationName:@"ShowText" object:textField.text];


//第三种,通知中创建一个携带对象或携带信息的通知并发送

[nc postNotificationName:@"ShowText" object:textField.text userInfo:[NSDictionary dictionaryWithObjectsAndKeys:textField.text,@"text",nil]];


//获取通知中心

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

[nc addObserver:self selector:@selector(ShowFunc:) name:@"showtext" object:nil];


-(void)ShowFunc:(NSNotification *)notify

{

    //获取通知携带的信息

    NSDictionary *infoDict = notify.userInfo;

    UILabel *label = (id)[self.view viewWithTag:10];

    label.text = [infoDict objectForKey:@"text"];

}


-(void)dealloc

{

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

    [nc removeObserver:self name:@"ShowText" object:nil];

    //[nc removeObserver:self];移除所有通知

}

总结:通知中心发送通知,通知中心接受通知,通知中心移除观察者


4.利用KVC传值

(在下一个界面设置上一个界面的属性值)kvc的传值方法和正向传值的方法原理都是一样的


注意:下面的用单例和全局变量传值基本上不适用知道就好了


5.单例

//(1.AppDelegate)

//保存输入的文字,保存到AppDelegate对象的属性

AppDelegate *del = [UIApplication sharedApplication].delegate;

del.text = textField.text;


//整个应用程序有一个单例对象UIApplication的对象,也只有一个代理,AppDelegate的对象也只有一个

AppDelegate *del = [UIApplication sharedApplication].delegate;

UILabel *label = (id)[self.view viewWithTag:10];

//读取单例属性存储的文字

label.text = del.text;


//(2.自定义一个单例)

//创建单例


//获取单例对象

SingleTon *single = [SingleTon shareSingleTon];

//用单例的属性保存输入的文字

single.text = textField.text;


//获取单例对象

SingleTon *single = [SingleTon shareSingleTon];

UILabel *label = (id)[self.view viewWithTag:10];

//读取单例对象的属性值

label.text = single.text;


6.全局变量

//声明一个全局变量

NSString *text;


//用全局变量去保存输入的文字

text = textField.text;


//说明text在别的文件声明的

extern NSString *text;


UILabel *label = (id)[self.view viewWithTag:10];

label.text = text;



你可能感兴趣的:(反向传值)