常用的传值方法
1.属性传值(正向)





这样就是正向的属性传值
2.block传值(反向)
思路:
1.首先,创建两个视图控制器,在第一个视图控制器中创建一个UILabel和一个UIButton,其中UILabel是为了显示第二个视图控制器传过来的字符串,UIButton是为了push到第二个界面
2.第二个界面的只有一个UITextField,是为了输入文字,当输入文字,并且返回第一个界面的时候,当第二个视图将要消失的时候,就将第二个界面上TextFiled中的文字传给第一个界面,并且显示在UILabel上
Demo:




效果:



补充:block相关知识点
http://www.jianshu.com/p/f4fa7aeb2035
http://www.jianshu.com/p/2aad46e3ea95
1.使用block时什么情况会发生引用循环,如何解决?
一个对象中强引用了block,在block中又强引用了该对象,就会发射循环引用。
解决方法是将该对象使用__weak或者__block修饰符修饰之后再在block中使用。
id weak weakSelf = self; 或者 weak __typeof(&*self)weakSelf = self该方法可以设置宏
id __block weakSelf = self;
或者将其中一方强制制空 xxx = nil。
检测代码中是否存在循环引用问题,可使用 Facebook 开源的一个检测工具 FBRetainCycleDetector

block使用注意点:


3.通知传值(反向)
Demo:





效果:



补充:通知相关知识点
NSNotification:
这个类可以理解为一个消息对象,其中有三个成员变量;observer是观察者(一般在控制器中是self),它监测通知中心是否有消息发送的那个对象
- name:这个成员变量是这个消息对象的唯一标识,用于辨别消息对象,必须与需要发送通知的名字一致,否则通知无法到达
- object:这个成员变量定义一个对象,可以理解为针对某一个对象的消息;是通知关联的对象,即谁发送的通知(看情况,有时传的值很多,可以通过模型过渡...);也就是监听哪个对象发出的通知,如果使用"nil"值,代表监听所有通知
- userInfo:这个成员变量是一个字典,可以用其来进行传值;也就是传递的附加信息(通知的内容)
NSNotificationCenter:
通信的特点是:为单例模式,可以实现一对多通信,每个应用程序都会有一个默认的通知中心;通知是观察者(observer)模式的一种,结构为:发布者->通知中心->接受者;
基本的使用过程:首先在需要接受数据的对象(或者控制器)注册通知,在需要发布通信的对象中上传通知



移除通知方法:

- 移除通知需要注意的坑:
了解:在了解控制器的生命周期之后,我们都知道viewWillAppear:方法是在控制器的view将要显示的时候调用的,而viewWillDisappear:方法是在控制器的view将要隐藏的时候调用。很多时候我们根据自身需要将相关代码逻辑添加到这两个方法中。
- 小结:
1、iOS7新增加了导航控制器侧滑手势,当触发侧滑返回时,会调用系统的viewWillDisappear:方法,取消侧滑返回时又会调用viewWillAppear:方法。
2、在做手势和通知等一系列操作之时要分情况考虑:若通知和手势是与UI相关的,如监听UITextField键盘的显示和隐藏通知等应该在viewWillAppear:方法中添加通知,在viewWillDisappear:方法中移除通知;而与UI无关的通知和手势,像自定义通知等,应该在viewDidLoad等一次性方法中添加,在dealloc方法中释放。
3、在viewWillAppear:、viewWillDisappear:、viewDidAppear:、viewDidDisappear:等类似于这种会多次调用的系统方法中添加代码时,一定要多考虑业务逻辑,以免出现不必要的麻烦。
相关详细讲解链接:
http://www.jianshu.com/p/ea2aadef413d
注意点:
1.接受者和发布者的通知名字必须一致
2.接受者的对象中注册使用完后应该移除通知,一般在dealloc中移除
3.通知可以用于传值,也可以用于其他地方;通知比较优雅,耦合性低
4.协议传值(反向)
Demo:




效果:



5.单例传值
Demo:
单例类:
.h文件
#import <Foundation/Foundation.h>
@interface Datahandle : NSObject
@property (nonatomic, strong) NSString *passVolud;
+(instancetype)sharedHandle;// 单例方法
@end
.m文件
#import "Datahandle.h"
@implementation Datahandle
// 1.重写init初始化方法(使用抛出异常的方式不让调用)
-(instancetype)init {
@throw [NSException exceptionWithName:@"Datahandle" reason:@"不允许使用" userInfo:nil];
return self;
}
// 2.废弃了系统的init方法,所以自己写一个私有的init方法(重新实现初始化)
-(instancetype)initPrivate {
if (self = [super init]) {
}
return self;
}
// 3.单例实现方法(系统线程加锁方式)
+(instancetype)sharedHandle {
static Datahandle *datahandle = nil;// 用static修饰,这个方法只走一次
@synchronized (self) {// 同步保护(互斥锁,保证线程安全)
if (!datahandle) {
datahandle = [[Datahandle alloc]initPrivate];// 用重新写的私有初始化
}
}
return datahandle;
}
// 方法二(传统创建方式)
//+(instancetype)sharedHandle{
//
// static Datahandle *datahandle = nil;
//
// if (!datahandle){
//
// datahandle = [[Datahandle alloc] init];
// }
// return datahandle;
//}
// 方法三 (线程方式--最优)
//+(instancetype)sharedHandle {
//
// static Datahandle *datahandle = nil;
// static dispatch_once_t onceToken; //给单例加了一个线程锁
//
// dispatch_once(&onceToken, ^{
//
// datahandle = [[Datahandle alloc] init];
// });
// return datahandle;
//}
@end




效果:



单例相关知识点
1.简介
就是一个实例,单例是全局都可以使用的唯一的一个类,相当于一个全局变量,它提供了对类的对象所提供的资源的全局访问点。因此需要用一种只允许生成对象类的唯一实例的机制;
作用:可以保证的程序运行过程,一个类只有一个示例,而且该实例易于供外界访问,从而方便地控制了实例个数,并节约系统资源(就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个))
2.单例实现思路
• 首先必须创建一个全局实例,通常存放在一个全局变量中,此全局变量设置为nil
• 提供工厂方法对该全局实例进行访问,检查该变量是否为nil,如果nil就创建一个新的实例,最后返回全局实例
• 全局变量的初始化在第一次调用工厂方法时会在+allocWithZone:中进行,所以需要重写该方法,防止通过标准的alloc方式创建新的实例
• 为了防止通过copy方法得到新的实例,需要实现-copyWithZone方法
• 只需在此方法中返回本身对象即可,引用计数也不需要进行改变,因为单例模式下的对象是不允许销毁的,所以也就不用保留
• 因为全局实例不允许释放,所以retain,release,autorelease方法均需重写
注意:
类只能有一个实例,并且必须从一个为人数值的访问点对其访问;这个唯一的实例只能通过子类化进行拓展,并且拓展的对象不会破坏客户端代码

3.常见的系统单例
UIApplication(应用程序实例)
NSNotificationCenter(通知)
NSFileManager(文件管理):
NSUserDefaults(应用程序设置):
UIScreen
NSApplication
NSFontManager
NSDocumentController
NSHelpManager
NSNull
NSProcessInfo
NSScriptExecutionContext
屏幕快照 2016-04-28 上午9.48.33.png
4.使用场景
http://blog.csdn.net/tanyujing/article/details/14160941
单例模式应用的场景一般发现在以下条件下:
1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
简单说就是:整个程序共用一份资源时(我们只需要对这份资源初始化一次)可以使用单例;例如:
1.设置单例类访问应用的配置信息
2.用户的个人信息登陆后用nsuserdefaults 存储,对登录类进一步采用单例封装方便全局访问
3.封装一个单例对应用多处对同一本地数据库进行操作
参考文章:http://blog.csdn.net/blueboyhi/article/details/51074372