iOS 的数据交给(数据传递)办法中,常用的办法有:参数传递、Delegate、Notification、Block、KVO 和 Target-Action。下面逐个说明下这几种办法:

1. 参数传递

这是最常用的一种办法了,便是在一个类中声明一个 public 的特点,提供给调用者,举个比方:

/* A.h */
@interface A : UIView;
@property (nonatomic, strong) UIButton *title;
@end
/* B.m */
A *a = [A alloc] init];
a.title = @"title";

这个便是最简单的参数传递的比方了,也是最常用的一种办法。

2. Delegate

在 iOS 中提到 delegate 天然便是想到 protocol,想想最初为了面试,还真不少背概念,其实也很好了解,举个比较形象的比方:

某神壕,想在深圳出售一套200方的房子(想想我干一辈子也买不起~~~),但神壕不想自己搞,然后交给了中介(delegate)去卖,但是神壕仍是有必定要求的,比方最少多少钱、最好能到达多少钱等等(protocol),而买家则必须到达这种要求(完成 protocol办法),神壕才会卖,不然他就不干。

看完神壕卖房的比方,我想应该能大约了解 delegate 和 protocol 的关系了。

举例个实际运用:

/* 头文件 */
/* 定义一个协议 */
@protocol YHPhotoPickerViewControllerDelegate <NSObject>
- (void)YHPhotoPickerViewController:(YHSelectPhotoViewController *)PhotoPickerViewController selectedPhotos:(NSArray *)photos;
- (void)selectedPhotoBeyondLimit:(int)count currentView:(UIView *)view;
@end
@interface YHSelectPhotoViewController : UIViewController
@property(weak, nonatomic) id<YHPhotoPickerViewControllerDelegate> pickerDelegate;
@end

完成办法:

/* 完成类中的办法 */
- (void)finshToSelectPhoto {
    if ([self.pickerDelegate respondsToSelector:@selector(YHPhotoPickerViewController:selectedPhotos:)]){
       // todo some thing
    }
}

在这儿将数据交给出去。先判断delegate是否存在,然后再判断是否完成的协议的相关内容(若不完成需求crash时能够在判断里加上断语),当delegate 和 protocol 都完成了,就能够进行数据的交给了。

调用办法:

@interface ViewController : UIViewController <YHPhotoPickerViewControllerDelegate>
#pragma mark - YHPhotoPickerViewController Delegate
- (void)YHPhotoPickerViewController:(YHSelectPhotoViewController *)PhotoPickerViewController selectedPhotos:(NSArray *)photos {
    // handle data
}
@end

这儿处理交给的数据,需求完成协议办法

3. Notification

Notification,这东西又爱又恨,一不小心就坑到不要不要的,这儿先不分析为什么,先说完成。Notification(观察者形式的一种完成) 和 Delegage 都是规划模块的一种,但是两种规划形式的运用场景不太一样。

先看下观察者形式(图片来自鬼话规划形式):

关于 iOS 中数据交给

这儿就不详细说规划形式,我看了下鬼话规划形式这本书,仍是说得比较形象,有兴趣的能够看下,但我仍是比较喜欢黑书那本。

在 iOS 中,apple 现已封装好了 Notification,不需求咱们完成,这儿咱们直接运用就能够了:

发送告诉:

// object 便是交给的参数了,假如想传递多个参数时,能够运用调集来传递
[[NSNotificationCenter defaultCenter] postNotificationName:@"NotificationName" object:nil];

再看上面,新手很容易被坑到,object 并不是交给的参数,看另一个接口:

关于 iOS 中数据交给

userInfo 才是要交给的参数,object 是用来做过滤告诉的,^_^ 有没有坑过呢,问下自己吧。

再看添加监听告诉的办法:

- (void)addObserver:(id)observer selector:(SEL)aSelector name:(NSNotificationName)aName object:(id)anObject;

这儿也有objct,别纠结,直接看苹果 api 文档就好了:

关于 iOS 中数据交给

接纳告诉:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sensorStateChange:) name:UIDeviceProximityStateDidChangeNotification object:nil];
- (void)sensorStateChange:(NSNotificationCenter *)notification { ... }

其实苹果的api文档现已写得很详细了,假如有对接口办法有疑问,仍是多去看下官方的接口文档。

4. Block

Block 能够了解为 OC 的匿名函数,也能够了解为 OC 中的一种特殊变量,它能够在两个方针之间将任意的代码块作为参数进行传递。

举个比方:

typedef void (^DictionaryResponseBlock)(NSDictionary *retDict);
typedef void (^errorBlock)(NSError *error);
+ (void)reqeustWeatherInfo:(NSString *)cityName
                      successCallback:(DictionaryResponseBlock)successCallback
                         failCallback:(errorBlock)failCallback;
[XXXXX reqeustWeatherInfo:@"cityName" successCallback:^(NSDictionary *retDict) {
                // 代码块(你要处理的操作)
            } failCallback:^(NSError *error) {
            }];

要害仍是 在两个方针之间将任意的代码块作为参数进行传递 这句话的了解,上面的代码实施便是把

^(NSDictionary *retDict) {
                // 代码块(你要处理的操作)
            }

这些代码块当作参数传递到别一个方针中运用。在运用block的时分,初学的时分遇到过很懵逼的问题,便是什么时分运用weak,是否需求strong回来,看到唐巧大神的大众号有几篇文章解说得非常好,便是self 持有 block,block 又持有 self 时,就会引起循环引证,这个时分就需求运用:

__weak __typeof(self)weakSelf = self;

这种状况,为避免block调用self时,self被开释的状况,就要运用:

__strong __typeof(weakSelf)strongSelf = weakSelf;
if (strongSelf) {
}

详细能够去看巧神的大众号。

5. KVO

KVO(Key – Value – Observer) 又是观察者形式的一种完成,简单点说便是键值监听者,指定的方针的特点被修改后,监听的方针就会收到告诉。

举例:

// 1.注册观察者
[user addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:user.name];
// 2.回调办法
- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context {
}
// 3.移除观察者
[user removeObserver:self forKeyPath:@"name"];
}

在这儿能够经过context的值进行数据交给。

6. Target-Action

Target-Action(方针-动作形式),看起来有点抽象化,简单点来说便是:当某工作发生时,咱们会xxx(方针,也能够说方针)的xxx办法(动作或举动)。

最简的比方便是button的点击工作,这个就不单独举例了。

###挑选何种交给办法 其实对于挑选何种交给办法,对我个人来说,这方面经历仍是不足够,这儿只介绍自己遇到的坑,有更好的建议的朋友望点拨。

7. 合理运用Notification

上面介绍过Notification时也说了,一不小心就坑得不要不要的,比方说你忘掉把某个监听给移除了,这个便是很苦逼的工作,心里是很酸爽的。这个主要是编码不规范导致的。另一人主要原因仍是Notification的影响面不行操控,没有办法承认处理地办法只要仅有,或许明确处理的地方,特别多人协助时就更加混乱。这儿尽管说了Notification的运用很多不好的地方,但并不是强调Notification的不好,只要最适宜的规划形式,没有好或许最坏的规划形式,所有能用的规划形式,都是前人的经历和总结,它们的存在都是经过了前人的检验的。比方网络状况的切换就很适宜运用Notification。

8. 少用block

其实能用block完成的东西都能够经过delegate来完成,但要区分怎样挑选的话,那便是看回调的内容,假如回调要做的东西都是共同的就挑选delegate;假如每次回调回来时要做的东西都不同,就挑选block。

block除了上面介绍的时分说过会或许导致循环引证,咱们能够weak引证来处理这个办法,但block仍是有或许延长了方针的生命周期,而delegate就不会有这种问题,由于它本身便是弱的引证。这儿为什么说尽量少用block,主要仍是由于深受其害啊,现在公司的项目,不管是在网络层仍是事务层,清一色的block,方才接手原来的项目时,每次调试到一半,我去,block,又一个block,又一个block,这个时分咱们根本不知道block里做了什么只能一个个跳进去查看,发现里边又有block,心里是各种草泥马的,一个办法里边有几个block,block里边还有block,这代码可读性真的感觉为0,一个办法有1,2百行的代码,混合着各个不同的任务,办法的单一性呢?

别一个问题,运用block的时分,回调的的代码和调用逻辑又放在一起了,很容易就出现那种一个办法几百行代码的状况,说好的办法单一性感觉又没有了。

9. 总结

合理运用Notification,少用block。这儿就只介绍这些了,其它的在后面的学习有所领会时再来弥补了,假如有更好见地的朋友,望指出,大家多共享交流。