iOS沙盒目錄結(jié)構(gòu)解析

出于安全考慮,iOS系統(tǒng)的沙盒機(jī)制規(guī)定每個(gè)應(yīng)用都只能訪問(wèn)當(dāng)前沙盒目錄下面的文件(也有例外,比如系統(tǒng)通訊錄能在用戶授權(quán)的情況下被第三方應(yīng)用訪問(wèn)),這個(gè)規(guī)則把iOS系統(tǒng)的封閉性展現(xiàn)的淋漓盡致。

一、沙盒中幾個(gè)主要的目錄

每個(gè)沙盒下面都有相似的目錄結(jié)構(gòu),如下圖所示(出自蘋果官方文檔):

沙盒1.jpg

每個(gè)應(yīng)用的沙盒目錄都是相似的,主要包含圖中所示的4個(gè)目錄:

1、MyApp.app
(1)存放內(nèi)容:該目錄包含了應(yīng)用程序本身的數(shù)據(jù),包括資源文件和可執(zhí)行文件等。程序啟動(dòng)以后,會(huì)根據(jù)需要從該目錄中動(dòng)態(tài)加載代碼或資源到內(nèi)存,這里用到了lazy loading的思想。
(2)整個(gè)目錄是只讀的:為了防止被篡改,應(yīng)用在安裝的時(shí)候會(huì)將該目錄簽名。非越獄情況下,該目錄中內(nèi)容是無(wú)法更改的;在越獄設(shè)備上如果更改了目錄內(nèi)容,對(duì)應(yīng)的簽名就會(huì)被改變,這種情況下蘋果官網(wǎng)描述的后果是應(yīng)用程序?qū)o(wú)法啟動(dòng),我沒實(shí)踐過(guò)。
(3)是否會(huì)被iTunes同步:否
2、Documents
(1)存放內(nèi)容:我們可以將應(yīng)用程序的數(shù)據(jù)文件保存在該目錄下。不過(guò)這些數(shù)據(jù)類型僅限于不可再生的數(shù)據(jù),可再生的數(shù)據(jù)文件應(yīng)該存放在Library/Cache目錄下。
(2)是否會(huì)被iTunes同步:是
3、Documents/Inbox
(1)存放內(nèi)容:該目錄用來(lái)保存由外部應(yīng)用請(qǐng)求當(dāng)前應(yīng)用程序打開的文件。
     比如我們的應(yīng)用叫A,向系統(tǒng)注冊(cè)了幾種可打開的文件格式,B應(yīng)用有一個(gè)A支持的格式的文件F,并且申請(qǐng)調(diào)用A打開F。由于F當(dāng)前是在B應(yīng)用的沙盒中,我們知道,沙盒機(jī)制是不允許A訪問(wèn)B沙盒中的文件,因此蘋果的解決方案是講F拷貝一份到A應(yīng)用的Documents/Inbox目錄下,再讓A打開F。
(2)是否會(huì)被iTunes同步:是
4、Library
(1)存放內(nèi)容:蘋果建議用來(lái)存放默認(rèn)設(shè)置或其它狀態(tài)信息。
(2)是否會(huì)被iTunes同步:是,但是要除了Caches子目錄外
5、Library/Caches
(1)存放內(nèi)容:主要是緩存文件,用戶使用過(guò)程中緩存都可以保存在這個(gè)目錄中。前面說(shuō)過(guò),Documents目錄用于保存不可再生的文件,那么這個(gè)目錄就用于保存那些可再生的文件,比如網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)。鑒于此,應(yīng)用程序通常還需要負(fù)責(zé)刪除這些文件。
(2)是否會(huì)被iTunes同步:否。
6、Library/Preferences
(1)存放內(nèi)容:應(yīng)用程序的偏好設(shè)置文件。我們使用NSUserDefaults寫的設(shè)置數(shù)據(jù)都會(huì)保存到該目錄下的一個(gè)plist文件中,這就是所謂的寫道plist中!
(2)是否會(huì)被iTunes同步:是
7、tmp
(1)存放內(nèi)容:各種臨時(shí)文件,保存應(yīng)用再次啟動(dòng)時(shí)不需要的文件。而且,當(dāng)應(yīng)用不再需要這些文件時(shí)應(yīng)該主動(dòng)將其刪除,因?yàn)樵撃夸浵碌臇|西隨時(shí)有可能被系統(tǒng)清理掉,目前已知的一種可能清理的原因是系統(tǒng)磁盤存儲(chǔ)空間不足的時(shí)候。
(2)是否會(huì)被iTunes同步:否

二、獲取主要目錄路徑的方式

1、沙盒目錄
NSLog(@"%@",NSHomeDirectory());  
輸出結(jié)果:/var/mobile/Applications/326640A7-6E27-4C63-BA5E-7391F203659A
2、tmp
  NSLog(@"%@",NSTemporaryDirectory());  
  輸出結(jié)果:/private/var/mobile/Applications/326640A7-6E27-4C63-BA5E-7391F203659A/tmp/  
3、Myapp.app
 NSLog(@"%@",[[NSBundle mainBundle] bundlePath]);  

 輸出結(jié)果:/var/mobile/Applications/326640A7-6E27-4C63-BA5E-7391F203659A/PhoneCall.app  
4、Document
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);  
NSString *path = [paths objectAtIndex:0];  
NSLog(@"%@",path);
輸出結(jié)果:/var/mobile/Applications/326640A7-6E27-4C63-BA5E-7391F203659A/Documents  
這里用到的NSSearchPathForDirectoriesInDomains方法需要解釋下,其聲明如下:
FOUNDATION_EXPORT NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);
該方法用于返回指定范圍內(nèi)的指定名稱的目錄的路徑集合。有三個(gè)參數(shù):
(1)directory:NSSearchPathDirectory類型的enum值,表明我們要搜索的目錄名稱,比如這里用NSDocumentDirectory表明我們要搜索的是Documents目錄。如果我們將其換成NSCachesDirectory就表示我們搜索的是Library/Caches目錄。
(2)domainMask:NSSearchPathDomainMask類型的enum值,指定搜索范圍,這里的NSUserDomainMask表示搜索的范圍限制于當(dāng)前應(yīng)用的沙盒目錄。還可以寫成NSLocalDomainMask(表示/Library)、NSNetworkDomainMask(表示/Network)等。
(3)expandTilde:BOOL值,表示是否展開波浪線~。我們知道在iOS中~的全寫形式是/User/userName,該值為YES即表示寫成全寫形式,為NO就表示直接寫成“~”。

三、參考文檔

蘋果官方文檔

https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40010672-CH1-SW1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容