常用的七种传值方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用的七种传值方式相关的知识,希望对你有一定的参考价值。

简单分享下,希望大牛们多多指点迷津,逐步修改,完善不足支持。借鉴之处,还请谅解

1、单例传值 :   <Singleton>

     单例模式:某个类只有一个实例,并提供静态实例创建方法,用于操作很频繁的实例(提升效率性能)

一、创建单例类:@property (strong, nonatomic) NSString *data;        static  Singleton *share=nil;

       +(Singleton *)getInstance{

           static dispatch_once_t once;   //GCD技术(多线程访问) 整个生命周期只执行一次

           dispatch_once(&once , ^{    share=[[self  alloc] init];  });         return  share ;    //本类对象初始化一次

 二、 运用到不同视图控制器中:  1、正向模态式:

       - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{

           A   :  Singleton *share=[Singleton   getInstance];    share.data=xx;   //单例类接收A的数据 
                    BViewController *b=segue.destinationViewController    //指定目标视图的对象b,跳转后的是b的实例化对象
         }     跳转后——B   :  Singleton *share=[Singleton   getInstance];       XX=share.data;  //B接收单例类数据
        2、反向:button监听,接收时 在-(void)didViewAppear{    接收单例类的数据   }

2、通知机制传值 NSNotificationCenter提供了一种更加解耦的方式。最典型的应用就是任何对象对可以发送通知到中心,同时任何对象可以监听中心的通知。

    1、发送通知的代码如下:

[[NSNotificationCenter defaultCenter]  postNotificationName:@”密码标识”  object:dataObj];     //& object:nil userInfo:dict ];
    2、注册接收通知的代码如下:

[[NSNotificationCenter defaultCenter]  addObserver:self   selector:@selector(receiveData:) name:@”密码标识”   object:nil];

    3、注册者可反复调用方法来接收数据,实现传值功能

-(void) receiveData:(NSNotification *)sender{

               xxx = sender.object ;       //接收传递过来的数据:&  sender.userInfo    :NSDictionary类型

}       注册通知的时候可以指定一个具体的广播者对象,但这不是必须的。你可能注意到了defaultCenter 。实际上这是你在应用中会使用到的唯一的中心。通知会向整个应用开放,因此只有一个中心。

同时还有一个NSDistributedNotificationCenter。这是用来应用间通信的。在整个计算机上只有一个该类型的中心。
     优点:  通知的发送者和接受者都不需要知道对方。可以指定接收通知的具体方法。通知名可以是任何字符串。
     缺点:  较键值观察需要多点代码。在删掉前必须移除监听者。不能传大量数值,只能让谁去做什么事。

3、属性传值:前向后传值。     <Segue传值>

    采用栈方式(第一个视图必须带有导航控制器)      // B视图中定义属性data,用于接收数据

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{      //A视图中push、pop

       BViewController *b=segue.destinationViewController;    b.data=XXX;    //把b 作为目的视图,接收数据   }

    //button按钮点击事件跳转下一个视图时,需要对第二个视图初始化,并作为目标视图控制器

4、方法传值:需求同属性传值

     通过使用方法传值,可以直接将方法与初始化方法合并,此时当触发 A 的按钮点击事件并跳转到 B 时,在按钮点击事件中可以直接通过 B 的初始化,将值保存在 A 中。首先 B 视图中需要有一个属性data用来存储传递过来的值:
1、重写初始化方法,用于传值:-(id)initWithData:(NSString *)data;
2、按钮响应:将方法传值与初始化写到一起:

        BViewController *b = [[BViewController alloc]initWithData:data]; //此时已经将值存在A中

        [self.navigationController pushViewController:b animated:YES];

5、协议传值  代替协议代理传值,主要时间点问题。  <Delegate>

      如何从A进入B,在B输入值后回传给A:使用Delegate(委托协议)。
   1、 A 遵守DataDelegate :        - (void)onclick:(NSString *)sender{   //现委托协议的方法    xx = sender;     }       //接收数据
   2、点击进入 B 的方法   

@property (nonatomic,weak) id <ButtonDelegate>delegate;       //传递值的对象为委托属性。实现委托协议的任何对象(id)

 [_delegate   onclick: dataB ];        //委托属性调用协议方法,传递数据

      [self dismissViewControllerAnimated:YES completion:nil];    //关闭模态  &present

6、Block传值 :参考http://liuyafang.blog.51cto.com/8837978/1551399

1.第一页中声明一个block,需要传入一个颜色,让当前的view变色

    //声明一个block,需要传入一个颜色,让当前的view变色

    void(^changeColor)(UIColor *color) = ^(UIColor *color){

        self.view.backgroundColor = color;

    };

2. 第一页中//block传值---------将block给第二个页面

    SecondViewController *secondVC = [[SecondViewController alloc] init];

    //block传值---------将block给第二个页面

    secondVC.block = changeColor;

3.第二页中定义--当block变量作为一个类的属性,必须要使用copy修饰

  //block传值---------将block给第二个页面

  //block传值 ---当block变量作为一个类的属性,必须要使用copy修饰

  @property (nonatomic , copy)void(^block)(UIColor *color);

4.在第二页中给block传值

    //block传值---------将传值给block

    NSArray *array = [NSArray arrayWithObjects:[UIColor yellowColor], [UIColor cyanColor], [UIColor greenColor], [UIColor brownColor], nil];

    self.block([array objectAtIndex:rand() % 4]);

7、数据共享:  app之间要共享数据,因为每个app都是sandbox。而有时候又不得不跟其它app之间共享数据

  • UIDocumentInteractionController 
    Availability: ios 3.2+
    具体用法参见:http://mobile.tutsplus.com/tutorials/iphone/previewing-and-opening-documents-with-uidocumentinteractioncontroller/

  • UIActivityViewController 
    Availability: iOS 6.0+

  • Shared Keychain Access
    这个要求app之间用的是同样的证书

  • Custom URL Scheme
    通过构造URL,把数据作为参数传递过去。 本地测试过,传递10000个字符都可以,不过不要太长,内存可能吃不消。

  • Web Service 通过dropbox或者其他第三方的服务来共享数据。

  • UIPasteboard + URL Scheme 通过URL scheme传递UIPasteboard的名称,然后通过UIPasteboard共享数据。
    微信iOS SDK应该采用的就是这种方式。
    不过在iOS 7上,这种方法会存在问题,如果采用这种方案,得赶紧想办法解决。

1) http://enharmonichq.com/sharing-data-locally-between-ios-apps/

2) http://stackoverflow.com/questions/17080074/ios7-beta-doesnt-allow-inter-app-communication-by-uipasteboard

以上是关于常用的七种传值方式的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序的组件间三种传值方式

三种传值方式遇上两个数的交换

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

iOS 页面间几种传值方式(属性,代理,block,单例,通知)

单例模式的七种实现

C#.net页面跳转的七种方法