1. 程式人生 > >iOS中的系統目錄(Documents、tmp、Library)、RunLoop的一些知識點

iOS中的系統目錄(Documents、tmp、Library)、RunLoop的一些知識點

### 學習內容 歡迎關注我的iOS學習總結——每天學一點iOS:https://github.com/practiceqian/one-day-one-iOS-summary #### 實現輪播圖需要注意的地方 1. 需要幾張輪播圖就設定UIScrollView的contentSize的寬度為自身的幾倍 - ```objective-c //設定高度為0是為了限制UIScrollView只能在x軸方向滾動,如果設定x為0那麼只能在y軸方向滾動 CGSizeMake(自身寬度*n,0) ``` 2. 使用NSTImer定時器定時滾動時避免迴圈引用 - 這裡一般使用系統的BLock方法加上\__weak和\__strong的使用 3. 給UISCrollView加上圖片時,每一張圖片的x方向位移是初始偏移量加上圖片下標*UISCrollView的寬度 - ```objective-c CGRectMake(初始偏移量+i*(bounds.size.width),0,bounds.size.width-2*初始偏移量,bounds.size.height) ``` 4. 定時器的使用需要及時的刪除/新增,同時注意建立定時器的方式 - 使用timerwithInterval建立的定時器不會自動新增到RunLoop中,需要手動開啟RunLoop ```objective-c [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; [[NSRunLoop mainRunLoop] addTimer:timer forMode: UITrackingRunLoopMode]; //或者直接新增到NSRunLoopCommonModes中 [[NSRunLoop mainRunLoop] addTimer:timer forMode: NSRunLoopCommonModes]; ``` - 通過timerWithTimeInterval和initWithFireDate方法創建出來的定時器,都需要手動加入到RunLoop中才會執行,否則不會執行;但是通過scheduledTimerWithTimeInterval創建出來的定時器是自動加入到RunLoop,而且會自動執行 - 當用戶拖動UIScrollView時需要及時的移除定時器,停止拖動時需要及時的加上定時器 ```objective-c //這裡可以設定兩個函式,addTimer,removeTimer -(void)addTimer{ __weak typeof(self) weakSelf = self; self.bannerTimer = [NSTimer timerWithTimeInterval:3.0 repeats:YES block:^(NSTimer * _Nonnull timer) { __strong typeof(weakSelf) strongSelf = weakSelf; [strongSelf changePage]; }]; [[NSRunLoop mainRunLoop]addTimer:self.bannerTimer forMode:NSDefaultRunLoopMode]; } -(void)removeTimer{ [self.bannerTimer invalidate]; self.bannerTimer = nil; } //scrollview即將開始被拖動 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ [self removeTimer]; } //scrollview即將停止拖動 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ [self addTimer]; } ``` #### iOS中的系統目錄 1. 獲取當前應用程式的根目錄 - ```objective-c NSString* homePath = NSHomeDirectory() ``` 2. 獲取應用程式的幾個主要目錄 - Documents - 儲存使用者建立的文件檔案的目錄,使用者可以通過檔案分享分享該目錄下的檔案,在iTunes和iCloud備份時會自動備份該目錄 - ```objective-c //NSSearchPathForDirectoriesInDomains返回的是一個字串陣列,但是數組裡面只有一個元素 NSString* docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; ``` - Library - 不建議在該目錄下儲存任何使用者相關資料,而是儲存APP執行需要的修改資料,使用者也可以根據自己的需要進行儲存 - Caches - 建議儲存資料快取使用,在使用者的磁碟空間已經使用完畢時可能刪除該目錄中的檔案,在APP試用期間不會被刪除,但是在APP沒有執行的時候系統可能會刪除,需要持久化的資料不建議儲存在該目錄下,防止被系統刪除 - preferences - 使用者偏好儲存目錄,使用NSUserDefaults或者CFPreferences介面儲存的資料都儲存在該目錄下,程式設計人員不需要對該目錄進行管理,iTunes和iCloud會自動對該目錄進行備份 - Application State - 用來儲存與使用者資料以外的所有檔案,如遊戲的新關卡,iTunes和iCloud會自動備份該目錄 - tmp - 該目錄用來儲存臨時使用的資料,程式設計人員應該在資料長時間不使用時主動刪除該目錄下的檔案,在APP不執行期間,系統可能刪除該目錄下的檔案,iTunes和iCloud不會備份該目錄的檔案 - SystemData(暫無介紹) 3. 綜上所述,我們儲存資料可以儲存在Documents、Application State目錄下,而preferences用於儲存系統介面資料不建議使用,而tmp目錄和cache目錄中的內容可能會被系統磁碟壓力緊張時刪除 #### 關於Runloop的一些知識點 1. RunLoop是什麼? - RunLoop是一種事件迴圈,一般的while迴圈會導致CPU進入忙等狀態,而RunLoop則是一種閒等待,當沒有事件時,RunLoop會進入休眠狀態,當有事件時,Runloop回去尋找相應的Handler處理事件,Runloop可以讓執行緒在需要做事的時候忙起來,在不需要的時候進入休眠狀態 ```objective-c do{ //獲取訊息 //處理訊息 }while(訊息!=退出) ``` - 一個Runloop物件,包含了一個執行緒,若干個mode,還有當前執行的mode - Runloop和執行緒是繫結在一起的,每個執行緒都有一個對應的Runloop物件,我們不能自己建立Runloop物件,但是可以獲取到系統提供的Runloop物件 - 主執行緒的Runloop會在系統啟動時完成啟動,其他執行緒的Runloop預設並不會啟動,需要我們手動啟動 2. RunLoop Mode - Mode可以視為事件的管家,一個Mode管理著各種事件 - Mode實際上是source,observer,timer的集合,不同的Mode把不同組的source,observer,timer隔絕開,Runloop在某個時刻只能執行在一個Mode下,處理這一個Mode下的source,observer,timer - 蘋果文件中提到的Mode共有五個 - NSDefaultRunLoopMode - NSConnectionReplyMode - NSModePanelRunLoopMode - NSEventTrackingRunLoopMode - NSRunLoopCommonModes - 但是公開暴露出來介面的只有NSDefaultRunLoopMode和NSRunLoopCommonModes - NSRunLoopCommonModes是一個Mode的集合,包含了NSDefaultRunLoopMode和NSEventTrackingRunLoopMode,並不是說RunLoop會執行在這兩種模式下,而是相當於分別註冊了default和eventtracking兩種模式。 3. RunLoop Source - RunLoopSource分為source,timer,observer三種,它們被稱作ModeItem 4. 獲取RunLoop - ```objective-c //獲取當前執行緒的RunLoop,子執行緒的RunLoop要在子執行緒獲取 +(NSRunLoop*)currentRunLoop; //獲取主執行緒的RunLoop +(NSRunLoop*)mainRunLoop;