iOS 开发总结(精华篇一)

1. Objective-C是动态运行时语言是什么意思?

主要是将数据类型的确定由编译时, 推迟到了运行时。
主要涉及两个概念: 运行时多态

运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象的指定方法。
多态:不同对象以自己的方式响应相同的消息的能力叫多态。
例如:生物类都有一个共同方法 - (void)eat;人属于生物,狗也属于生物,都继承相同东西,实现各自的eat,但是调用时我们只需调用各自eat方法。

不同对象以自己的方式响应了相同的消息,因此可以说运行时是多态的基础。

2. 讲一下MVC和MVVM,MVP?

MVC:

MVC 模式
  • Model 与 View 永远不能相互通信,只能通过 Controller 传递。
  • Controller 可以直接与 Model 对话(读写调用 Model),Model 通过 Notification 和 KVO 机制与 Controller 间接通信。
  • Controller 可以直接与 View 对话,通过 outlet,直接操作 View,outlet 直接对应到 View 中的控件,View 通过 action 向 Controller 报告事件的发生(如用户 Touch 了我),Controller 是 View 的直接数据源(数据很可能是 Controller 从 Model 中取得并经过加工了)。Controller 是 View 的代理(delegate),以同步 View 和 Controller。

MVP:

MVP 模式将 Controller 改名为 Presenter(提出者,任命者),同时改变了通信方向。


MVP 模式
  • 各部分之间的通信都是双向的。
  • View 和 Model 不发生关系,都通过 Presenter 传递。
  • View 非常薄,不部署任何业务逻辑,称为"滚动视图"(Passive View),即没有任何主动性,而 Presenter 非常厚,所有部署都部署在这里。

3. 为什么代理要用weak?代理的delegate和dataSource有什么区别?block和代理的区别?

  • weak 修饰的对象不持有 delegate 这个对象,delegate 这个对象的销毁由外部控制。
    strong修饰的对象强引用,持有这个对象,外部不能销毁 delegate 对象,引起循环引用。

  • DataSource 是数据源,用来连接数据的,提供获取数据方法。
    Delegate 是代理函数,提供一些操作方法。

  • 代理和 block 都是回调机制,代理方法比较多,分散,block 代码比较集中统一。
    block 出栈需要将数据从栈内存拷贝到堆内存,对象引用计数加1,使用完或者 block 置为nil 后才清除。
    delegate 只是保存了一个对象指针,直接回调,没有额外消耗。

4.属性的实质是什么?包括哪几个部分?属性默认的关键字都有哪些?@dynamic关键字和@synthesize关键字是用来做什么的?

属性的本质:
@property = ivar + setter + getter;

属性包括三部分:

  • 线程安全:nonatomic(线程不安全),atomic(线程安全,setter、getter)。

  • 内存管理:strongretainassignweakcopy
    - strong:ARC 模式下,对对象进行强引用,释放旧值,设置新值,引用计数加1。
    - retain:MRC 模式下,对对象进行强引用,释放旧值,设置新值,引用计数加1;
    - assign:修饰基本数据类型,也可修饰 OC 对象,释放旧值,不保留新值,修饰的属性被释放后内存地址仍在,没有被释放,没被置为 nil,造成野指针,当再次使用这个属性,发生崩溃。
    - weak:只能修饰 OC 对象,弱引用,修饰对象被释放后,指针地址也被置为 nil。

  • 读写权限:readwrite(可读可写)、readonly(只读)。

@dynamic 系统不会自动生成 settergetter 方法,编译时不会报错,运行时用到 settergetter 方法会崩溃。
@synthesize(默认) 系统自动生成 settergetter 方法。

5. 属性的默认关键字是什么?

对于基本数据类型:atomicreadwriteassign;
对于普通 OC 对象:atomicreadwritestrong

6. NSString为什么要用copy关键字,如果用strong会有什么问题?(注意:这里没有说用strong就一定不行。使用copy和strong是看情况而定的)

因为 NSStringNSDictionaryNSArray 有对应的可变类型,他们经常会用到赋值操作,为保证字符串数值不会无意间被改动,应该在设置新属性值是拷贝一份。
若使用 strong,那么这个属性就可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。

7. 如何令自己所写的对象具有拷贝功能?

若想另自己写的代码具有拷贝功能,则需要实现 NSCoping 协议,如果自定义的对象分为可变版本和不可变版本,那么就要同时实现NSCopingNSMutableCoping协议。
例子:

ViewController.m

#import "ViewController.h"
#import "SecondViewController.h"
#import "PersonModel.h"

@interface ViewController ()

@end

@implementation ViewController
{
    PersonModel *model;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    model = [[PersonModel alloc] init];
    model.name = @"张三";
    model.sex = @"男";
}

- (void)viewWillAppear:(BOOL)animated
{
    NSLog(@"%@---%@---%@", [self class], model.name, model.sex);
}

- (IBAction)buttonClicked:(UIButton *)sender
{
    SecondViewController *vc = [[SecondViewController alloc] init];
    vc.model = model;
    [self.navigationController pushViewController:vc animated:YES];
}

Person.h

#import <Foundation/Foundation.h>

@interface PersonModel : NSObject <NSCopying>

@property (nonatomic, copy) NSString *name;

@property (nonatomic, copy) NSString *sex;

@end

Person.m

#import "PersonModel.h"

@implementation PersonModel

//- (id)copyWithZone:(NSZone *)zone
//{
//    PersonModel *model = [PersonModel allocWithZone:zone];
//    return model;
//}

@end

SecondViewController.h


#import <UIKit/UIKit.h>
#import "PersonModel.h"

@interface SecondViewController : UIViewController

@property (nonatomic, strong) PersonModel *model;

//@property (nonatomic, copy) PersonModel *model;

@end

SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor redColor];
    
    _model.name = @"哈哈";
    
    NSLog(@"%@---%@", _model.name, _model.sex);
}
@end

使用 Strong 传输自定义 Model 输出结果:
2017-06-13 18:03:06.739 NSCoping[8834:261731] ViewController---张三---男
2017-06-13 18:03:53.154 NSCoping[8834:261731] 哈哈---男
2017-06-13 18:04:12.714 NSCoping[8834:261731] ViewController---哈哈---男

分析:第一次打印为进入首页时数据,
第二次打印为跳转后修改了 name 后打印的结果,
第三次打印为返回首页打印的结果,
第三次打印结果中因为 SecondViewcontroller.h 中 Person 使用了 strong, 不需要遵循 NSCoping 协议,返回首页时把原来的值也给修改了。

使用 copy 传输自定义 Model 输出结果:
2017-06-13 18:10:07.668 NSCoping[8979:265669] ViewController---张三---男
2017-06-13 18:10:09.105 NSCoping[8979:265669] 哈哈---(null)
2017-06-13 18:10:10.997 NSCoping[8979:265669] ViewController---张三---男

发现第三次的打印结果和第一次相比没有变化。

代码demo

8. 可变集合类 和 不可变集合类的 copy 和 mutablecopy有什么区别?如果是集合是内容复制的话,集合里面的元素也是内容复制么?

例子:

mutablecopy:

ViewController.h

- (IBAction)buttonClicked:(UIButton *)sender
{
    NSArray *dataSource = @[@"张三", @"李四", @"王五"];
    NSLog(@"%p", dataSource);
    
    ThirdViewController *vc = [[ThirdViewController alloc] init];
    vc.dataSource = [dataSource mutableCopy];
    [self.navigationController pushViewController:vc animated:YES];
}

ThirdViewController.h

#import <UIKit/UIKit.h>

@interface ThirdViewController : UIViewController

@property (nonatomic, copy) NSArray *dataSource;

@end

ThirdViewController.m

#import "ThirdViewController.h"

@interface ThirdViewController ()

@end

@implementation ThirdViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    NSLog(@"%p", _dataSource);
}


@end

输出结果
2017-06-14 10:28:58.155 NSCoping[2369:51665] 0x600000057850
2017-06-14 10:28:58.164 NSCoping[2369:51665] 0x60000004bd00

copy

ViewController.h

- (IBAction)buttonClicked:(UIButton *)sender
{
    NSArray *dataSource = @[@"张三", @"李四", @"王五"];
    NSLog(@"%p", dataSource);
    
    ThirdViewController *vc = [[ThirdViewController alloc] init];
    vc.dataSource = [dataSource mutableCopy];
    [self.navigationController pushViewController:vc animated:YES];
}

输出结果:
2017-06-14 10:33:06.690 NSCoping[2433:53481] 0x600000052660
2017-06-14 10:33:06.698 NSCoping[2433:53481] 0x600000052660

由此得出结论:

**不可变集合的 copy 是浅拷贝,mutablecopy 是深拷贝,重新拷贝了对象的指针地址。
同理实验可以得出:可变集合的 copy 和 mutablecopy 都是深拷贝,因为对象的指针地址都发生了改变。
**

9. 为什么IBOutlet修饰的UIView也使用weak关键字?

当我们把控件拖到 StoryBoard 上时,相当于把这个控件加到了视图控制器的 View上,View 上有一个 addSubView 属性,这个属性是一个数组,里面所有的 View 都添加在这个数组中, View 对加到它上面的对象是强引用,当我们使用 Outlet属性时,我们仅仅在 ViewController中使用,没有必要拥有它,所有是weak

10. nonatomic和atomic的区别?atomic是绝对的线程安全么?为什么?如果不是,那应该如何实现?

nonatomicatomic主要区别在于系统生成的 setter/getter 方法不一样。如果自己写 setter/getter,那 atomic/nonatomic/retain/assign/copy 这些关键字只起提示作用,写不写都一样。

对于atomic的属性,系统生成的setter/getter会保证getset操作的完整性,不受其他线程影响。比如,线程 A 的 getter方法运行到一半,线程 B 调用了setter方法,那么线程 A 的getter还是能得到一个完整的对象。

nonatomic就不能保证线程完整了,所有,nonatomicatomic速度要快。

不过atomic并不能保证线程安全,如果 A 调了getter,与此同时,线程 B、线程 C 都调了setter,---那最后线程 A get 到的值,3种都有可能:可能 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值, 也可能是 C set 的值。

11. 了解hitText 方法事件传递?


hitText作用: 当在一个屏幕上添加一个屏幕罩,但又不影响下面 view 的操作时,也就是透过屏幕罩对下面的 view 进行操作。

举例说明:(陌陌面试题)

问题描述:将 UIScrollView 和 UIView 都添加到 Controller 的 view 上,可以拖动 UIView, UIScrollView 也可以滚动。


示例图

调用过程:

iOS系统检测到手指触摸(Touch)操作时会将其放入当前活动Application的事件队列,UIApplication会从事件队列中取出触摸事件并传递给key window(当前接收用户事件的窗口)处理,window对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,称之为hit-test view。

window对象会在首先在view hierarchy的顶级view上调用hitTest:withEvent:,此方法会在视图层级结构中的每个视图上调用pointInside:withEvent:,如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是hit-test view。

hitText:withEvent:调用方法处理流程:

  1. 首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
  1. 若返回NO,则hitTest:withEvent:返回nil;
  2. 若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;
  3. 若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
  4. 如所有子视图都返回非,则hitTest:withEvent:方法返回自身 self 。

主要代码:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    //1.判断下自己能否接收事件
    if (self.alpha <= 0.01) {
        return nil;
    }

    //2.判断是否在当前区域内点击
    if ([self pointInside:point withEvent:event] == NO) {
        return nil;
    }
    else
    {
        //3.把当前坐标系上的点转换成父视图上的点
        CGPoint newPoint  = [self convertPoint:point toView:self.superview];
        
        //4.获取想要响应的 view
        UIView *view = self.superview.subviews[0];
        
        if (CGRectContainsPoint(view.frame, newPoint)) {
            return view;
        }
        else
        {
            //如果没有比自己合适的子控件,最适合的 View 就是自己
            return self;
        }
    }
}

demo 下载地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 基础 1. 为什么说Objective-C是一门动态的语言? 2. 讲一下MVC和MVVM,MVP? 3. 为...
    波妞和酱豆子阅读 3,318评论 0 46
  • 1、截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的数据,分别输出它们 ...
    强子ly阅读 2,935评论 8 46
  • 把网上的一些结合自己面试时遇到的面试题总结了一下,以后有新的还会再加进来。 1. OC 的理解与特性 OC 作为一...
    AlaricMurray阅读 2,562评论 0 20
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,139评论 30 470
  • 1,Search Bar 怎样去掉背景的颜色(storyboard里只能设置background颜色,可是发现cl...
    以德扶人阅读 2,345评论 2 50