ios中反向传值得几种方法

    xiaoxiao2021-03-25  101

    #pragma mark - 反向传值

    1.代理

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

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

    @protocol ShowTextDelegate <NSObject>

    @required

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

    @optional

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

    @end

    @interface SecodViewController : UIViewController

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

    @end

    //调用代理方法

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

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

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

        self.view.backgroundColor = color;

    }

    @interface RootViewController ()<ShowTextDelegate>

    //建立代理关系

    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;

    转载请注明原文地址: https://ju.6miu.com/read-19903.html

    最新回复(0)