Unit 6
Posted ZeroOnet
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unit 6相关的知识,希望对你有一定的参考价值。
什么是沙盒机制?沙盒包含了哪些文件,分别的应用场景是什么? |
SandBox(沙盒)是ios管理App的一种安全机制,它规定了应用程序只能访问系统为它创建的文件夹里的内容。下图是一个App的文件夹分级:
- Documents:Apple建议将程序中创建的文件或者浏览到的文件数据存储到这个文件夹下,iTunes备份和恢复时会包含这个文件夹;
- Library:
-> Caches:程序在使用过程中产生的数据缓存会在这个文件夹下体现出来;
-> Cookies:服务器存放在客户端的用于记录用户信息的小型文本文件(加密);
-> Preference:存储程序的设置和一些状态信息,在程序中使用NSUserDefault存储的像用户名及密码等用户数据会以属性列表的形式存储在这个位置。 - tmp:用于存放临时创建的文件。
当收到内存警告时,App会有怎样的处理流程? |
这里有各种iOS设备的内存阈值,当内存量达到这样的一个限制值时,App就会被OS强制退出!而这之前系统就会向App发送Memory Warning
消息,最开始将通过AppDelegate
的如下方法响应:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
然后将内存警告以通知的形式发送给所有的视图控制器,视图控制器就会调用如下方法:
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
//....
在这里面你应当做的是清除App业务或者缓存数据,而不是手动将视图控制器所持有的视图置为nil
,这里是不这样做的原因及更好应对内存警告的一些方法。另外在唐巧的技术博客中还提到过OS对内存的优化技巧:
- 当一段内存被分配时,它会被标记成
In use
, 以防止被重复使用。当内存被释放时,这段内存会被标记成Not in use
,这样,在有新的内存申请时,这块内存就可能被分配给其它变量。 CALayer
包括具体的bitmap
内容的私有成员变量类型为CABackingStore
, 当收到MemroyWarning
时,CABackingStore
类型的内存区会被标记成volatile
。volatile
表示这块内存可能会再次被原变量重用。
nib 对象从SB 中加载到内存到释放经历了怎样的过程? |
nib
文件装载代码包括文件中创建的对象的实例化、配置以及重建对象之间的连接,其中两个重要的对象是File's Owner
、First Responder
。
- - 概述 - -
前者是一个占位符(placeholder
)对象,在nib
文件加载的时候不会被创建,而是应该在你的代码中创建并将它传递给加载nib
的代码,因为这个对象连接着你的应用代码和nib
文件中的对象。更具体地说,它是管理nib
文件中包含的对象的控制器对象。在Xcode中,你可以File's Owner
与nib
中对象的连接关系。当你加载nib
文件时,装载代码会用你指定的更换对象来重建这些连接关系,这样你就可以引用nib
文件中的对象和自动接收接口对象的消息。(即这个占位符实际对象会在装载过程中被赋予有意义的值——nib
文件的所属对象,然后在重新建立对象与它之间的连接引用关系。)
后者同样是一个占位符对象,它代表了应用中动态确定的响应链的第一个响应对象。因为应用的响应链不能在设计时决定,First Responder
(第一响应者)充当一个替身目标来响应任何需要针对于应用的响应链的行为消息。例如UITextField
的一系列方法都需要其成为第一响应者才能响应。当你将nib
文件加载到内存时,你不需要做任何管理或者替换第一响应者占位符对象的事情,AppKit
和UIKit
框架会在应用当前的配置的基础上建立并持有第一响应者。
- - Nib对象的生命周期 - -
对象的加载过程
当你用NSNib
或者NSBundle
来加载和初始化nib
文件中的对象时,nib
装载代码会有如下几步操作:
加载
nib
文件内容和任何引用的源文件到内存中:❖ 将整个
nib
对象图表的原始数据加载到内存但不解档。❖ 将所有与
nib
文件相互关联的自定义图片和声音资源加载到内存并将它们分别加到Cocoa image / sound cache
缓存。解档
nib
对象图表数据并初始化对象。每个新对象如何初始化取决于对象的类型和它在归档时是如何编码的。nib
装载代码使用如下规则来决定对象使用哪种初始化方法:❖ 默认情况下,将要初始化的对象会接收到
initWithCoder:
消息。在MacOS中,标准对象包括
views
、cells
、menus
和由系统提供的并在Xcode
默认库中可用的view controllers
。它还包括使用自定义插件加入到库中的第三方对象。即使你改变了这样一个对象的所属类,Xcode
会将标准对象编码到nib
文件中并且告诉archiver
在解档时将对象所属类交换成你自定义的类。在iOS中,任何实现了
NSCoding
协议的对象将使用initWithCoder:
方法来初始化。它包含了所有UIView
和UIViewController
的子类,无论它是Xcode
默认库提供的还是你自己定义的类。❖ 在MacOS中,自定义的
views
收到initWithFrame:
消息。自定义
views
是在Xcode
没有有效实现的NSView
的子类。特别地,这些是你在程序中定义用来提供自定义可视内容的views
。自定义views
不包换由默认库或者第三方插件集成的标准系统views
。当偶然使用到自定义
view
时,Xcode
会编码一个特殊的NSCustomView
对象到你的nib
文件中。自定义view
对象包含了你指定的它需要被创建成的真正的view
的子类信息。在加载时,NSCustomView
对象会发送一个alloc
和initWithFrame:
消息给它真正所属的view
类然后互相交换view
对象。这样做的效果的是真正的view
对象在nib
加载过程中处理随后的交互行为。iOS中的自定义
view
不会使用initWithFrame:
来初始化。重建
nib
文件中对象之间的所有连接(行为,输出口,绑定),包括File's Owner
和其他占位符对象。连接的建立方法与平台有关:❖ 输出口连接(
Outlet connections
)◆ 在MacOS中,
nib
装载代码首先试图使用对象自身的方法来重新连接输出口。对于每个输出口,Cocoa
会寻找setOutletName:
这种形式的方法,如果能够找到,就会调用它。如果不能找到,Cocoa
会搜索对象与输出口相匹配的实例变量然后试着直接赋值。要是实例变量也没有找到的话,将不会建立任何连接。设置输出口也发生在任何注册了观察者的
KVO
通知,这些通知可能会发生在所有内部对象连接被重建之前,并一定在任何对象调用awakeFromNib
方法之前。◆ 在iOS中,
nib
装载代码使用setValue:forKey:
(KVC
)方法来重建每个输出口连接。该方法同样寻找一个合适的访问方法并在其他方式失败时返回,此时同样没有任何连接建立成功。第二种情况同MacOS。
❖ 行为连接
◆ 在MacOS中,
nib
装载代码使用源对象的setTarget:
和setAction:
方法来建立到目标对象的连接。如果目标对象不能响应行为方法,连接将不会建立。如果目标对象为nil
,就由响应链来处理行为。◆ 在iOS中,
nib
装载代码使用addTarget:action:forControlEvents:
方法来为UIControl
对象配置行为。如果目标为nil
,行为也将由响应链来处理。❖ 绑定(
Bindings
)MacOS支持的特性,iOS没有(与运行时为对象关联属性概念类似)。
Cocoa
使用bind:toObject:withKeyPath:options:
方法为源对象来创建它和它的目标对象之间的关联。发送
awakeFromNib
消息给nib
文件中定义了匹配的selector
的合适的对象。◆ 在MacOS中,这个消息会发送给任何定义了此方法的接口对象。定义了该方法的
File's Owner
和任何占位符对象也会受到此消息。◆ 在iOS中,这个消息只会发送给通过
nib
装载代码来初始化的接口对象。File's Owner
、First Responder
和任何其他的占位符对象不会接收到此消息。展示所有在
nib
文件中Visible at launch time
属性使能的windows
。
nib
装载代码调用对象的awakeFromNib
方法的顺序是没有保证的。在MacOS中,Cocoa试图最后调用File's Owner
的awakeFromNib
方法,但这种行为并不能保证。如果你需要在nib
文件中配置对象而不是在加载时,最适当的时机是nib
加载完毕返回之后。在那时,所有的对象都已经被创建并初始化和准备使用了。
管理nib文件中对象的生命周期
你每次使用NSBundle
或者NSNib
类来加载nib
文件时,底层代码会创建该文件中的对象的新副本,然后将它们返回给你。(nib
装载代码不会尝试从之前加载的结果中循环利用nib
文件中的对象)如果有必要,你需要确保你已经获得新的对象图表并在你使用完之后解除这种持有关系。典型的情况是,你需要强引用顶层对象来保证它们不会被销毁。你不需要强引用对象图表中级别较低的对象,因为它们由它们的上一级(parents
)管理。并且你应该尽可能降低造成强引用循环的风险。
从实际使用出发,iOS和MacOS的输出口都应该被定义为属性(properties
)。除了File's Owner
和nib
文件中顶层对象应该是strong
强引用外,输出口通常是weak
弱引用的。因为:
- 对于
view controller's view
或者a window controller's window
来说,你创建的输出口是它们的subviews
,输出口只是subviews
的引用,而不是拥有所有权。 - 强引用输出口通常指向框架类。(例如,
UIViewController's view
或者NSWindowController's window
输出口)
参考资料
App developer documents:Nib Files
以上是关于Unit 6的主要内容,如果未能解决你的问题,请参考以下文章
iOS 6.1 中的 *** 从 TextFieldOnEditingDidEnd 内部调用成为第一响应者时