iOS面试题目一
1.#import和#include的区别,@class代表什么?
2.谈谈Objective-C的内存管理方式及过程
3、Objective-C有私有方法吗?私有变量呢?
4、Objective-C有多继承吗?没有的话用什么代替?
5、浅拷贝与深拷贝的区别是什么
6、属性readwrite、readonly、assign、retain、copy、nonatomic各是什么作用,在哪种情况下用?
7、什么情况使用weak关键字,相比assign有什么不同?
8、@synthesize和@dynamic分别有什么作用?
9、obj-c中的类方法和实例方法有什么本质区别和联系?
10 线程与进程的区别和联系?
10.1、 iOS 中的多线程
11多线程核心概念
11.1 三种多线程的对比
12.__block和__weak修饰符的区别
13 .static 关键字的作用
14 -----待添加----
15 类别(`延展/类目category`)的作用
16 循 环 引 用 的 产 生 原 因,以 及 解 决 方 法
17 代 理 的 作 用
17.1 UIView和CALayer的区别
17.2 iOS中的响应者链的工作原理
18 NSNotification、Block、Delegate和KVO的区别
18.1 KVC 与 KVO
20 @public、@protected、@private 它们的含义与作用
21 isMemberOfClass 和 isKindOfClass 联系与区别
22 UITableViewCell上有个UILabel,显示NSTimer实现的秒表时间,手指滚动cell过程中,label是否刷新,为什么?
22.1 使用block有什么好处?使用NSTimer写出一个使用block显示(在UILabel上)秒表的代码。
23 TCP和UDP的区别于联系
24 TCP连接的三次握手
25 ASIHttpRequest、AFNetWorking之间的区别
26 如何进行真机调试
27 APP发布的上架流程
28 如何进行网络消息推送
28 SDWebImage原理
29 对NSUserDefaults的理解
30 对沙盒的理解
31 堆和栈的区别
------------------------------
32. 对于Run Loop的理解
------------------------------
33 Struct 与 Class 的区别
34. 介绍一下观察者模式
35. 动画
1.#import和#include的区别,@class代表什么?
1. #include指令是c语言中原来就有的包含头文件的指令,会产生重复包含;
2. #import会包含这个类的所有信息,包括实体变量和方法,
3. @class只是告诉编译器这是个类,至于这些类是如何定义的,暂时不用考虑。
4. 防止循环引用: 如果A–>B, B–>A这样的相互依赖关系,如果使用#import来相互包含,那么就会出现
编译错误,如果使用@class在两个类的头文件中相互声明,则不会有编译错误出现.
5. 在编译效率方面考虑,如果你有100个头文件都#import了同一个头文件,都需要重新编译, @class则不会.
2、谈谈Objective-C的内存管理方式及过程
内存管理黄金法则:谁使对象的引用计数+1,谁就负责管理使该对象的引用计数-1。
说说内存管理的过程:
在MRC下,对于需要手动释放的对象的内存管理,我们通过release使对象引用计数-1,若其引用计数变成0,则对象会被立刻释放掉。对于autorelease交给自动释放池管理的对象,每个runloop循环结束就会去自动释放池中使所有autorelease类型对象的引用计数减一,若变成0,则释放之。
在ARC下,我们没有不能直接调用retain/release来管理释放,都是交给自动释放池来管理的。因此,若创建临时变量,想要使用完就释放之,需要在临时变量放到新创建的自动释放池里,这样就可以使用完后就到达了自动释放池的一个循环,就会去使对象引用计数减一,变成0后释放之。
最后:对于交给自动释放池管理的对象,是在每个run loop事件循环结束时才会去使对象引用计数减一,此时引用计数为0的才会得到释放。
3、Objective-C有私有方法吗?私有变量呢?
在Objective-C中,没有实实存在的私有方法。通常所谓的私有方法就是放在.m文件中声明和实现,外部不能直
接看到而已,但是若我们知道有这么一个API,我们是可以调用的。比如,在苹果上架会因为使用了苹果的所
谓的私有API而被拒,而这个所谓的私有API就是指苹果没有公布出来,但是我们通过其它方式可以看到苹果的
内部有这样一个API可以实现某些不公开的功能。
私有变量是有的,可以通过@private来声明私有变量。比如:
@interface HYBTestModel: NSObject {
@private NSString *_privateName;
}
4、Objective-C有多继承吗?没有的话用什么代替?
Objective-C没有多继承,这是去掉C++中多继承的特性,改成使用protocol来代替。Cocoa中所有的类都是NSObject的子类,这是正确的。
5、浅拷贝与深拷贝的区别是什么
浅拷贝就是指针拷贝(指向原有内存空间),而深拷贝是内容拷贝(有新的内存空间)。
6、属性readwrite、readonly、assign、retain、copy、nonatomic各是什么作用,在哪种情况下用?
作用分别是:
• readwrite:代表可读可写,会生成getter和setter方法
• readonly:代表只读,只生成getter方法,不会生成setter方法
• assign: 修饰基本数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等等。
• retain:MRC下才能手动使用,与ARC下的strong一样,指定强引用,引用计数加1
• copy:代表拷贝,也是强引用,引用计数加1,进行指针拷贝
• nonatomic:代表非原子操作,非线程安全,但可提高性能
7、什么情况使用weak关键字,相比assign有什么不同?
使用weak关键字的主要场景:
• 在ARC下,在有可能出现循环引用的时候往往要通过让其中一端使用weak来解决,比如: delegate代理属性,通常就会声明为weak。
• 自身已经对它进行一次强引用,没有必要再强引用一次时也会使用weak。比如:自定义 IBOutlet控件属性一般也使用weak,当然也可以使用strong。
相比assign不同之处:
• weak关键字只能用于对象,对于基本类型不能使用
• assign既可以用于对象,也可以用于基本类型,但是只是简单地进行赋值操作而已
8、@synthesize和@dynamic分别有什么作用?
分析:
@property有两个对应的词,一个是@synthesize,,另一个是@dynamic。
参考答案:
• @synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。
• @dynamic告诉编译器:属性的setter与getter方法由用户自己实现,不自动生成。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter 方法,编译的时候没问题,但是当程序运行到 instance.var = someVar,由于缺setter方法会导致程序崩溃;或者当运行到someVar = var 时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。
10 线程与进程的区别和联系?
区别
1 进程: 一个具有一定独立功能的程序关于某个数据集合的一次运行活动。可以理解成一个运行中的应用程序。
2 线程: 程序执行流的最小单元,线程是进程中的一个实体。
联系
1. 一个进程至少拥有一个线程——主线程,也可以拥有多个线程;
2. 一个线程必须有一个父进程。多个进程可以并发执行;
3. 一个线程可以创建和撤销另一个线程;
4. 同一个进程中的多个线程之间可以并发执行。
10.1、 iOS 中的多线程 更多
多线程核心概念: 一个任务 / 两种队列 / 两种函数, 详见11
GCD是(Grand Central Dispatch)的缩写 ,从系统级别提供的一个易用地多线程类库,具有运行时的特点,
能充分利用多核心硬件。GCD的API接口为C语言的函数,函数参数中多数有Block.
NSOperation与Queue
NSOperation是一个抽象类,它封装了线程的细节实现,我们可以通过子类化该对象,加上NSQueue来同面向
对象的思维,管理多线程程序。具体可参看这里:一个基于NSOperation的多线程网络访问的项目。
NSThread
NSThread是一个控制线程执行的对象,它不如NSOperation抽象,通过它我们可以方便的得到一个线程,
并控制它。但NSThread的线程之间的并发控制,是需要我们自己来控制的,可以通过NSCondition实现。
定时器与线程的区别;
• 定时器;可以执行多次,默认在主线程中。
• 线程:只能执行一次。
11. 多线程核心概念
1. 一个任务: 执行什么操作;
2. 执行任务的两种队列:
(1)并发队列(Concurrent Dispatch Queue): 可以让多个任务并发(同时)执行;
(2)串行队列(Serial Dispatch Queue):一个任务执行完毕后,再执行下一个任务.
2.1 并发队列和串行队列的区别: 任务的执行方式不同
3. 执行任务的两种函数:
(1)同步函数dispatch_sync < synchronous>: 一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。;
(2)异步函数dispatch_async <asynchronous>: 同时去做两件或者多件事。比如边听歌边看报。
3.1 同步和异步区别:能不能开启新的线程
- 并行/并发
1. 并行是CPU的多核芯同时执行多个任务
2. 并发是单核CPU交替执行两个任务
11.1 三种多线程的对比
• NSThread
每个NSThread对象对应一个线程,真正最原始的线程。
1)优点:NSThread 轻量级最低,相对简单。
2)缺点:手动管理所有的线程活动,如生命周期、线程同步、睡眠等。
• NSOperation
自带线程管理的抽象类。
1)优点:自带线程周期管理,操作上可更注重自己逻辑。
2)缺点:面向对象的抽象类,只能实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
• GCD更多用法
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。
1)优点:最高效,避开并发陷阱。
2)缺点:基于C实现。
12.__block和__weak修饰符的区别:
1. __block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2. __weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3. __block对象可以在block中被重新赋值,__weak不可以。
13 .static 关键字的作用
1.函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次,
因此其值在下次调用时仍维持上次的值;
2.在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;
3.在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 它的模块内;
4.在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
5.在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。
14 -----待添加----
15 类别(延展/类目category
)的作用
• 给系统原有类添加方法,不能扩展属性。如果类别中方法的名字跟系统的方法名一样,在调用的时候类别中的方法优先级更高;
• 分散类的实现:如:
• + (NSIndexPath *)indexPathForRow:(NSInteger)row
inSection:(NSInteger)section
原本属于NSIndexPath的方法,但因为这个方法经常使用的表的时候调用、跟表的关系特别密切,因此把这个方法一类别的形式、声明在UITableView.h中。
• 声明私有方法,某一个方法只实现,不声明,相当于私有方法。
• 类别不能声明变量,类别不可以直接添加属性。property描述setter方法,就不会报错。
优点:
• 不需要通过增加子类而增加现有类的行为(方法),且类目中的方法与原始类方法基本没有区别;
• 通过类目可以将庞大一个类的方法进行划分,从而便于代码的日后的维护、更新以及提高代码的阅读性;
缺点:
• 无法向类目添加实例变量,如果需要添加实例变量,只能通过定义子类的方式;
• 类目中的方法与原始类以及父类方法相比具有更高优先级,如果覆盖父类的方法,可能导致super消息的断裂。因此,最好不要覆盖原始类中的方法。
16 循 环 引 用 的 产 生 原 因,以 及 解 决 方 法
• 产生原因:对象A和对象B相互引用了对方作为自己的成员变量,只有自己销毁的时候才能将成员变量的引用
计数减1。对象A的销毁依赖于对象B的销毁,同时对象B销毁也依赖与对象A的销毁,从而形成循环引用,此时,
即使外界没有任何指针访问它,它也无法释放。
解决方法:
• 事先知道存在循环引用的地方,在合理的位置主动断开一个引用,是对象回收;
• 使用弱引用的方法。
17 代 理 的 作 用
• 代理又叫委托,是一种设计模式,代理是对象与对象之间的通信交互,代理解除了对象之间的耦合性。
• 改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。
• 代理的属性常是assign的原因:防止循环引用,以至对象无法得到正确的释放。
17.1 UIView和CALayer的区别
1、UIView是CALayer的代理;
2、UIView是处理事件,CALayer绘制
17.2 iOS中的响应者链的工作原理
1. 每一个应用有一个响应者链,我们的视图结构是一个N叉树(一个视图可以有多个子视图,一个子视图同一时刻
只有一个父视图),而每一个继承UIResponder的对象都可以在这个N叉树中扮演一个节点。
2. 当叶节点成为最高响应者的时候,从这个叶节点开始往其父节点开始追朔出一条链,那么对于这一个叶节点
来讲,这一条链就是当前的响应者链。响应者链将系统捕获到的UIEvent与UITouch从叶节点开始层层向下
分发,期间可以选择停止分发,也可以选择继续向下分发。
18 NSNotification、Block、Delegate和KVO的区别
• 代理是一种回调机制,且是一对一的关系,通知是一对多的关系,一个对向所有的观察者提供变更通知;
• 效率:Delegate比NSNOtification高;
• Delegate和Block一般是一对一的通信;
• Delegate需要定义协议方法,代理对象实现协议方法,并且需要建立代理关系才可以实现通信;
• Block:Block更加简洁,不需要定义繁琐的协议方法,但通信事件比较多的话,建议使用Delegate;
18.1 KVC 与 KVO
KVC、KVO概述
1. KVC(NSKeyValueCoding) "键-值 编码"是一种间接访问对象的属性的机制,
在Object2.0之后系统提供了(.)语法来访问属性,在此之前我们需要用KVC来访问。
2. KVO(NSKeyValueObserving) "键-值 监听"定义了这样一种机制,
当对象属性值发生变化的时候我们能收到一个通知。
1. KVC是一种间接访问对象属性的机制。
2. KVO是基于KVC来实现的。
19 谓词的认识
Cocoa框架中提供了一个NSPredicate的类,
该类主要用于指定过滤器的条件, 每一个对象通过谓词进行筛选,
判断条件是否匹配。
20 @public、@protected、@private 它们的含义与作用
• @public:对象的实例变量的作用域在任意地方都可以被访问 ;
• @protected:对象的实例变量作用域在本类和子类都可以被访问 ;
• @private:实例变量的作用域只能在本类(自身)中访问 .
21 isMemberOfClass 和 isKindOfClass 联系与区别
• 联系:两者都能检测一个对象是否是某个类的成员
• 区别:isKindOfClass 不仅用来确定一个对象是否是一个类的成员,也可以用来确定一个对象是否派生自该类的类的成员 ,而isMemberOfClass 只能做到第一点。
• 举例:如 ClassA派 生 自NSObject 类 , ClassA *a = [ClassA alloc] init];,[a isKindOfClass:[NSObject class]] 可以检查出 a 是否是 NSObject派生类 的成员,但 isMemberOfClass 做不到。
22 UITableViewCell上有个UILabel,显示NSTimer实现的秒表时间,手指滚动cell过程中,label是否刷新,为什么?
这是否刷新取决于timer加入到Run Loop中的Mode是什么。Mode主要是用来指定事件在运行循环中的优先级的,分为:
• NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
• UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
• UIInitializationRunLoopMode:run loop启动时,会切换到该mode
• NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
苹果公开提供的Mode有两个:
• NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
• NSRunLoopCommonModes(kCFRunLoopCommonModes)
• 在编程中:如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。当我们滚动的时候,也希望不调度,那就应该使用默认模式。但是,如果希望在滚动时,定时器也要回调,那就应该使用common mode。
22.1 使用block有什么好处?使用NSTimer写出一个使用block显示(在UILabel上)秒表的代码。
- 代码紧凑,传值、回调都很方便,省去了写代理的很多代码。
- NSTimer封装成的block,具体实现。
实现方法:
__weak typeof(self) weakSelf = self;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.7
target:[NSBlockOperation blockOperationWithBlock:^{ weakSelf.secondsLabel.text = ...
}]
selector:@selector(main)
userInfo:nil
repeats:NO
];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
使用GCD实现计时功能--下篇文章
23 TCP和UDP的区别于联系
• TCP为传输控制层协议,为面向连接、可靠的、点到点的通信;
• UDP为用户数据报协议,非连接的不可靠的点到多点的通信;
• TCP侧重可靠传输,UDP侧重快速传输。
24 TCP连接的三次握手
• 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
• 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包,即SYN+ACK包,此时服务器进入SYN+RECV状态;
• 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次状态。
25 ASIHttpRequest、AFNetWorking之间的区别
• ASIHttpRequest功能强大,主要是在MRC下实现的,是对系统CFNetwork API进行了封装,支持HTTP协议的CFHTTP,配置比较复杂,并且ASIHttpRequest框架默认不会帮你监听网络改变,如果需要让ASIHttpRequest帮你监听网络状态改变,并且手动开始这个功能。
• AFNetWorking构建于NSURLConnection、NSOperation以及其他熟悉的Foundation技术之上。拥有良好的架构,丰富的API及模块构建方式,使用起来非常轻松。它基于NSOperation封装的,AFURLConnectionOperation子类。
• ASIHttpRequest是直接操作对象ASIHttpRequest是一个实现了NSCoding协议的NSOperation子类;AFNetWorking直接操作对象的AFHttpClient,是一个实现NSCoding和NSCopying协议的NSObject子类。
• 同步请求:ASIHttpRequest直接通过调用一个startSynchronous方法;AFNetWorking默认没有封装同步请求,如果开发者需要使用同步请求,则需要重写getPath:paraments:success:failures方法,对于AFHttpRequestOperation进行同步处理。
• 性能对比:AFNetworking请求优于ASIHttpRequest;
AFNetWorking大致原理
AFNetWorking是对NSURLConnection和NSURLSession的各自的一层包装;
- 写一个
单例
,开辟新的线程, 保证安全性以及只开辟一块内存空间; - AFN内部开了一条专门用来访问网络请求的线程, 使用
NSThread
; - 添加一个runloop, 保证执行网络获取
26 如何进行真机调试<以下创建均为开发测试版的证书/描述文件>
• 1.首先需要用钥匙串创建一个钥匙(key);
• 2.将钥匙串上传到官网,获取iOS Development证书;
• 3.创建App ID即我们应用程序中的Boundle ID;
• 4.添加Device ID即UDID;
• 5.通过勾选前面所创建的证书:App ID、Device ID;
• 6.生成mobileprovision文件<描述文件>;
• 7.先决条件:申请开发者账号 99美刀/299美刀, 从xcode7开始可以免费真机测试
• 注意 8.个人版(99美刀)可以上架AppStore, 企业版(299美刀)不可以上架AppStore, 通过企业分发形式安装, 将IPA放在七牛云存储/蒲公英等等.
27 APP发布的上架流程
• 注意 个人版(99美刀)可以上架AppStore, 企业版(299美刀)不可以上架AppStore, 通过企业分发形式安装, 将IPA放在七牛云存储/蒲公英等等.
• 1.登录应用发布网站添加应用信息;
• 2.创建/下载/安装发布证书与描述文件<步骤参考26.真机测试, 改为正式版即可>;
• 3.选择发布证书,使用Archive编译发布包,用Xcode将代码(发布包)上传到服务器;
• 4.等待审核通过;
• 5.生成IPA:菜单栏->Product->Archive.
28 如何进行网络消息推送
屏幕快照 2016-06-13 下午4.56.45.pngAPP端需要做的
1. App ID(唯一标识一个App程序)
2. Provisioning Profile(App程序的发布需要它,所以推送通知只能在真机上测试)
3. Device Token(设备标识,这个是推送通知功能中特有的)
后台需要的
1. SSL Certificate 授权证书
2. Private Key
推送的所有步骤
* Provider :应用自己的服务器;
* APNS :Apple Push Notification Service的简称,苹果的PUSH服务器;
1. 移动设备应用启动时注册消息推送;
2. APNS返回该设备注册的唯一设备标示deviceToken;
3. 移动设备向Provider提供deviceToken;
4. Provider向APNS发送<SSL Certificate>和<Private Key>以及需要<推送给设备的消息>
5. APNS将消息根据deviceToken推送给指定设备
SDWebImage: 一个异步下载图片并且支持缓存的UIImageView分类。
1. 先从内存图片缓存查找是否有图片,如果内存中已经有图片缓存,SDImageCacheDelegate回调imageCache:didFindImage:forKey:userInfo:到SDWebImageManager, 并展示图片
2. 如果缓存中没有,生成NSInvocationOperation添加到队列开始从硬盘查找图片是否已经缓存
3. 根据URLKey在硬盘缓存目录下尝试读取图片文件,这一步是在NSOperation进行的操作,所以会主线程进行回调notifyDelegate:
4. 如果有图片就展示
5. 如果没有, 共享或重新生成一个下载器SDWebImageDownloader开始下载图片
6. connectionDidFinishLoading:数据下载完成后交给SDWebImageDecoder做图片解码处理;
7. 图片解码处理在一个NSOperationQueue完成,不会拖慢主线程UI。如果有需要对下载的图片进行二次处理,最好也在这里完成,效率会好很多;成功后
8. 通知所有的downloadDelegates下载完成,回调给需要的地方展示图片
9. 将图片保存到SDImageCache中,内存缓存和硬盘缓存同时保存。写文件到硬盘也可以单独NSInvocationOperation完成,避免拖慢主线程.
29 对NSUserDefaults的理解
NSUserDefaults:系统提供的一种存储数据的方式,主要用于保存少量的数据,默认存储到library下的Preferences文件夹。
30 对沙盒的理解
• 每个iOS应用都被限制在“沙盒”中,沙盒相当于一个加了仅主人可见权限的文件夹,及时在应用程序安装过程
中,系统为每个单独的应用程序生成它的主目录和一些关键的子目录。苹果对沙盒有几条限制:
• 1. 应用程序在自己的沙盒中运作,但是不能访问任何其他应用程序的沙盒;
• 2. 应用之间不能共享数据,沙盒里的文件不能被复制到其他
• 应用程序的文件夹中,也不能把其他应用文件夹复制到沙盒中;
• 3. 苹果禁止任何读写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中;
• 4. 沙盒目录里有三个文件夹:Documents——存储
• 应用程序的数据文件,存储用户数据或其他定期备份的信息;
• Library下有两个文件夹,Caches存储应用程序再次启动所需的信息,
• Preferences包含应用程序的偏好设置文件,不可在这更改偏好设置;
temp存放临时文件即应用程序再次启动不需要的文件。
• 获取沙盒根目录的方法,有几种方法:用NSHomeDirectory获取。
• 获取Document路径:
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).
31 堆和栈的区别
• 栈区(stack)由编译器自动分配释放 ,存放方法(函数)的参数值, 局部变量的值等,栈是
向低地址扩展的数据结构,是一块连续的内存的区域。即栈顶的地址和栈的最大容量是系统预先规定好的。
• 堆区(heap)一般由程序员分配释放, 若程序员不释放,程序结束时由OS回收,向高地址扩展
的数据结构,是不连续的内存区域,从而堆获得的空间比较灵活。
• 碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使
程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远
都不可能有一个内存块从栈中间弹出.
• 分配方式:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。
静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是
不同的,他的动态分配是由编译器进行释放,无需我们手工实现。
• 分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的
寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的
,它的机制是很复杂的。
• 全局区(静态区)(static),全局变量和静态变量的存储是放在一块 的,初始化的全局变量
和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。
• 文字常量区—常量字符串就是放在这里的。程序结束后由系统释放。
• 程序代码区—存放函数体的二进制代码
32. 对于Run Loop的理解
1. RunLoop,字面意思为循环圈, 一直调度任务, 有任务则调用, 没有时则休眠;
2. 默认情况下:一个线程一次只能执行一个任务,执行完任务后就会退出线程。主线程执行完即时任务时会继续等待接收事件而不退出;
3. 每一个线程都有其对应的RunLoop,只是默认只有主线程的RunLoop是启动的,其它子线程的RunLoop默认
是不启动的,若要启动则需要手动启动;
在一个单独的线程中,如果需要在处理完某个任务后不退出,继续等待接收事件,则需要启用RunLoop;
4. 实质上,对于子线程的runloop默认是不存在的,因为苹果采用了懒加载的方式。如果我们
没有手动调用[NSRunLoop currentRunLoop]的话,就不会去查询是否存在当前线程的RunLoop,也就不会去加载,更不会创建。
33 Struct 与 Class 的区别
(http://blog.csdn.net/yuliu0552/article/details/6717915)
共同点:
1. 都可以包含成员函数;
2. 都能继承;
3. 都能实现多态;
区别:
struct是public的,class是private的。
1. **struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的**
2. 当你觉得你要做的更像是一种数据结构的话,那么用struct,如果你要做的更像是一种对象的话,那么用class。
3.struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。
34. 介绍一下观察者模式
1. 含义: 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
2. 何时使用: 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
3. 举例子: 西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水招来一个老乌龟,这个乌龟就是观察者,他观察菩萨洒水这个动作。
4. 使用场景 :
4.1. 有多个子类共有的方法,且逻辑相同。
4.2、重要的、复杂的方法,可以考虑作为模板方法。
优缺点
**优点:** 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
**缺点:**
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
iOS观察者模式
1. 在iOS中观察者模式的实现有三种方法:Notification、KVO以及标准方法。
2. 标准方法:标准方法的实现是这样的:Subject(主题)知道所有的观察者,但是不知道它们的类型。下面我们就从创建Subject和Observer(观察者)的协议(protocol)开始。
35.想自己学动画请转至github, 该系列Demo是学习英文iOS Animations by Tutorials, 所整理的汉语文档与Demo;
iOS Animations by Tutorials更多精彩内容请关注“IT实战联盟”哦~~~
IT实战联盟.jpg