iOS笔试题

匿名网友 匿名网友 发布于: 2016-05-09 00:00:00
阅读 215 收藏 0 点赞 0 评论 0

1 . 简要描述观察者模式,并运用此模式编写一段代码;

观察者模式(Observer)是指一个或多个对象对另一个对象进行观察,当被观察对象发生变化时,观察者可以直接或间接地得到通知,从而能自动地更新观察者的数据,或者进行一些操作。

 

具体到iOS的开发中,实现观察者模式常用的方式有KVO和Notification两种。

 

两者的不同在于,KVO是被观察者主动向观察者发送消息;Notification是被观察者向NotificationCenter发送消息,再由NotificationCenter post通知到每个注册的观察者。

 

2 . 如何理解MVVM框架,它的优点和缺点在哪?运用此框架编写一段代码,建议采用ReactiveCocoa库实现;

MVVM框架相对于传统的MVC来说,主要区别在于把原本在C中(ViewController)的业务逻辑、网络请求、数据存储等操作和表现逻辑,分离到ViewModel中,从而使ViewController得到精简

 

MVC中,Controller同时操作Model和View;MVVM中,ViewModel作为一个过渡,Model的数据获取和加工由ViewModel负责,得到适合View的数据,利用绑定机制,使得View得以自动更新。

 

优点: 层次更加分明清晰 代码简洁优雅 减少VC的复杂性 代码和界面完全分离 方便测试

 

缺点: MVVM需要使用数据绑定机制,对于OS X 开发,可以直接使用Coocoa Binding,对于iOS,没有太好的数据绑定方法,可以使用KVO,但如果需要绑定的属性太多的话,需要编写大量的selector代码。

 

ReactiveCocoa提供了一种很方便优雅的绑定机制。

 

3 . 解释以下代码的内存泄漏原因

@implementation HJTestViewController

 

… …

 

– (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

 

    HJTestCell *cell = [tableView dequeueReusableCellWithIdentifier:@”TestCell” forIndexPath:indexPath];

    [cell setTouchBlock:^(HJTestCell *cell) {

        [self refreshData];

    }];

 

   return cell;

}

 

… …

 

@end

原因:

 

[cell setTouchBlock:^(HJTestCell *cell) {

    [self refreshData];

}];

产生内存泄露的原因是因为循环引用

 

在给cell设置的TouchBlock中,使用了__strong 修饰的self,由于Block的原理,当touchBlock从栈复制到堆中时,self会一同复制到堆中,retain一次,被touchBlock持有,而touchBlock又是被cell持有的,cell又被tableView持有,tableView又被self持有,因此形成了循环引用:self间接持有touchBlock,touchBlock持有self

 

一旦产生了循环引用,由于两个object都被强引用,所以retainCount始终不能为0,无发释放,产生内存泄漏

 

解决办法: 使用weakSelf解除touchBlock对self的强引用

 

__weak __typeof__(self) weakSelf = self;

[cell setTouchBlock:^(HJTestCell *cell) {

    [weakSelf refreshData];

}];

如果在block中多次使用 weakSelf的话,可以在block中先使用strongSelf,防止block执行时weakSelf被意外释放 对于非ARC,将 __weak 改用为 __block 即可

评论列表
文章目录