KVC查找順序
KVC(Key-Value Coding)在查找屬性值時會按照以下順序進行查找:
1. 直接訪問實例變量:KVC 首先嘗試直接訪問與屬性名相對應的實例變量,如果找到則直接返回對應的值。
2. 調用屬性的訪問方法:如果沒有找到與屬性名對應的實例變量,KVC 將嘗試調用屬性的訪問方法(getter)來獲取屬性的值。KVC 默認會按照一定的命名規則尋找屬性的訪問方法,例如對于名為 `name` 的屬性,KVC 將嘗試調用 `name`、`getName`、`isName`、`_name`、`_isName` 的方法,按照優先級依次查找,找到第一個存在的訪問方法就會返回對應的值。
3. 訪問容器屬性的值:如果屬性是一個容器(如 NSArray、NSSet),KVC 會進一步查找容器內的對象的屬性。例如,如果有一個名為 `persons` 的屬性,它是一個包含多個 Person 對象的 NSArray,可以使用 KVC 來訪問 `persons` 數組中所有對象的某個屬性。
4. 訪問集合運算符的值:KVC 提供了一些集合運算符(如 @avg、@sum、@count、@max、@min),可以在容器屬性上使用這些運算符獲取特定的值。
5. 訪問內部屬性:KVC 可以遞歸地訪問內部屬性,例如訪問 `person.address.city` 這樣的屬性路徑,KVC 會依次查找 `person` 對象的 `address` 屬性,然后再在 `address` 對象上查找 `city` 屬性。
總結:KVC 在查找屬性值時會先嘗試直接訪問實例變量,然后調用屬性的訪問方法,接著查找容器屬性的值,再使用集合運算符,最后遞歸地訪問內部屬性。如果在以上步驟中找到了屬性的值,則返回對應的值;如果未找到,則會拋出異常。
@avg、@sum、@count、@max、@min
NSArray *numbers = @[@10, @20, @30, @40];
NSNumber *average = [numbers valueForKeyPath:@"@avg.self"];
NSLog(@"Average: %@", average); // Output: Average: 25
NSArray *numbers = @[@10, @20, @30, @40];
NSNumber *sum = [numbers valueForKeyPath:@"@sum.self"];
NSLog(@"Sum: %@", sum); // Output: Sum: 100
NSArray *array = @[@"Apple", @"Banana", @"Orange"];
NSNumber *count = [array valueForKeyPath:@"@count"];
NSLog(@"Count: %@", count); // Output: Count: 3
NSArray *numbers = @[@10, @20, @30, @40];
NSNumber *maxValue = [numbers valueForKeyPath:@"@max.self"];
NSLog(@"Max Value: %@", maxValue); // Output: Max Value: 40
NSArray *numbers = @[@10, @20, @30, @40];
NSNumber *minValue = [numbers valueForKeyPath:@"@min.self"];
NSLog(@"Min Value: %@", minValue); // Output: Min Value: 10
對比NSThread,NSOperation,GCD
功能 | NSThread | NSOperation | GCD |
---|---|---|---|
并發操作 | 需要手動創建和管理線程 | 使用NSOperationQueue管理操作隊列 | 使用dispatch_queue管理并發隊列 |
線程管理 | 需要手動管理線程生命周期 | 由NSOperationQueue管理線程生命周期 | 由GCD自動管理線程生命周期 |
任務依賴關系 | 不支持 | 支持 | 支持 |
取消操作 | 需要手動取消線程 | 可以通過取消操作對象來取消任務 | 可以通過取消dispatch操作來取消任務 |
任務優先級 | 不支持 | 支持 | 支持 |
隊列類型 | 單一隊列 | NSOperationQueue支持串行和并發隊列 | dispatch_queue支持串行和并發隊列 |
線程同步 | 需要手動使用鎖來實現線程同步 | 支持使用NSLock、NSCondition等進行線程同步 | 支持使用信號量、互斥鎖等進行線程同步 |
錯誤處理 | 需要手動處理錯誤 | 支持通過設置completionBlock來處理錯誤 | 支持通過設置錯誤處理函數或回調來處理錯誤 |
可擴展性 | 受限于手動創建和管理線程的復雜性 | 支持自定義子類擴展操作 | 可以使用block來封裝自定義任務邏輯 |
編程模型 | 顯式線程管理,需要手動編寫線程代碼 | 高級抽象,提供操作對象和隊列來管理任務 | 高級抽象,使用block和隊列來管理任務 |
跨平臺支持 | 支持 | 支持 | 僅限于Apple平臺 |
總體而言,NSThread是較低級的線程管理方式,需要手動創建和管理線程,靈活性較高但使用相對復雜。NSOperation提供了更高級的抽象,可以管理任務之間的依賴關系和優先級,并提供更好的錯誤處理機制。GCD是一種輕量級的異步編程解決方案,使用block和隊列來管理任務,具有高性能和簡潔的語法。NSOperation和GCD都是建立在NSThread之上的更高級別的抽象,并提供更好的可讀性和可維護性。
選擇適當的方案取決于具體的需求和項目要求。如果需要更底層的控制和靈活性,可以選擇NSThread;如果需要更高級的任務管理和錯誤處理,以及跨平臺支持,可以選擇NSOperation;如果追求簡潔性、高性能和易用性,并且在Apple平臺上開發,可以選擇GCD。
下面是對常見的鎖的比較:
鎖類型 | 特點 | 使用場景 |
---|---|---|
OSSpinLock | 自旋鎖,忙等待 | 競爭不激烈、鎖持有時間短的情況下 |
pthread_mutex | 互斥鎖,阻塞等待 | 線程同步、競爭激烈、資源占用時間長的情況下 |
NSLock | Objective-C互斥鎖,阻塞等待 | 線程同步、Objective-C環境下 |
NSRecursiveLock | 可重入鎖,同一線程可多次加鎖 | 遞歸調用、同一線程多次加鎖的情況下 |
NSCondition | 條件鎖,支持線程等待和喚醒 | 線程間通信、線程同步 |
NSConditionLock | 條件鎖,支持多個條件和加鎖解鎖操作 | 多個條件的線程同步 |
dispatch_semaphore | 信號量鎖,控制并發數量 | 控制并發線程的數量 |
pthread_rwlock | 讀寫鎖,支持多個讀者和單個寫者 | 讀寫分離場景 |
os_unfair_lock (iOS 10+) | 低級別自旋鎖,內部優化,比OSSpinLock更高效,不會出現優先級反轉問題 | 競爭不激烈、鎖持有時間短的情況下(iOS 10+及macOS 10.12+使用) |
atomic | 原子操作鎖,提供基本的線程安全性 | 單一屬性的讀寫操作 |
選擇適當的鎖取決于具體的使用場景和需求。對于競爭不激烈、鎖持有時間短的情況,可以考慮使用輕量級的自旋鎖(如OSSpinLock、os_unfair_lock)。對于競爭激烈、資源占用時間長的情況,可以選擇互斥鎖(如pthread_mutex、NSLock)。如果需要支持線程等待和喚醒,可以使用條件鎖(如NSCondition)。讀寫分離場景可以考慮使用讀寫鎖(如pthread_rwlock)。在Objective-C環境下,可以使用NSLock、NSRecursiveLock等。在GCD中,可以使用dispatch_semaphore進行控制并發數量。對于簡單的原子操作,可以使用atomic屬性來提供基本的線程安全性。
需要根據具體的需求和場景來選擇合適的鎖,避免死鎖、優先級反轉等問題,并保證線程安全性和性能。
下面是對常見的數據存儲方式的比較:
數據存儲方式 | 特點 | 使用場景 |
---|---|---|
UserDefaults | 簡單的鍵值對存儲,適用于少量的用戶配置數據 | 用戶配置、偏好設置等 |
Property List | 使用plist文件存儲數據,支持多種數據類型 | 小型數據、配置文件等 |
SQLite | 關系型數據庫存儲,支持復雜的查詢和事務操作 | 大量結構化數據、復雜查詢需求 |
Core Data | 面向對象的數據存儲和管理框架,支持對象關系映射和多線程并發 | 復雜數據模型、需要對象關系映射的場景 |
Realm | 輕量級的移動數據庫,支持快速讀寫和實時數據同步,對象映射簡單 | 移動端應用、需要高性能讀寫和實時同步的場景 |
Key-Value Store | 非關系型鍵值存儲,適用于大規模分布式系統,支持快速讀寫和分布式存儲 | 大規模分布式系統、鍵值對存儲的需求 |
File System | 使用文件系統存儲數據,靈活性高,可自定義數據結構和存儲方式 | 大文件、自定義數據結構的存儲需求 |
Network Storage | 數據存儲在網絡服務器上,通過網絡請求進行讀寫 | 分布式系統、多端數據同步的需求 |
Cloud Storage | 數據存儲在云端,可跨設備訪問和同步,提供云服務提供商的數據存儲服務 | 跨設備訪問、數據同步和備份的需求 |
選擇適當的數據存儲方式取決于具體的需求和場景。如果只是存儲少量的用戶配置數據或偏好設置,可以使用UserDefaults。對于小型數據或配置文件,可以選擇Property List。如果需要復雜的查詢和事務操作,可以使用SQLite。Core Data適用于復雜的數據模型和對象關系映射需求。Realm提供了高性能讀寫和實時同步的特性,適用于移動端應用。鍵值存儲適用于大規模分布式系統。如果需要自定義數據結構和存儲方式,可以使用文件系統。網絡存儲和云存儲適用于分布式系統、多端訪問和數據同步的需求。
需要根據具體的數據量、性能要求、查詢需求、并發性等因素綜合考慮,選擇合適的數據存儲方式。
比較[UIImage imageNamed:]
和[UIImage imageWithContentsOfFile:]
的使用和特性:
[UIImage imageNamed:] |
[UIImage imageWithContentsOfFile:] |
|
---|---|---|
使用方式 | 從應用程序的資源包中加載圖像 | 從指定的文件路徑加載圖像 |
緩存 | 自動緩存圖像 | 不緩存圖像 |
內存占用 | 可能由于緩存而消耗更多內存 | 內存占用較低,適用于大型或頻繁使用的圖像 |
文件路徑 | 不需要完整的文件路徑 | 需要完整的文件路徑 |
錯誤處理 | 如果找不到圖像名稱,則返回nil
|
如果文件路徑無效或無法加載圖像,則返回nil
|
適用場景 | 應用程序內置圖像資源 | 大型圖像或特定的文件位置 |
如何從磁盤快速顯示圖片,SDWebImage做了什么?
要從磁盤快速顯示圖片,可以使用SDWebImage庫來實現。SDWebImage是一個廣泛使用的iOS圖片加載和緩存庫,它提供了許多功能來優化圖片加載和顯示的性能。
下面是SDWebImage的主要功能和它在從磁盤快速顯示圖片方面的工作原理:
下面是SDWebImage的主要功能以及它在從磁盤快速顯示圖片方面的工作原理的表格展示:
主要功能 | 工作原理 |
---|---|
異步下載和緩存網絡圖片 | 通過使用NSURLConnection或NSURLSession進行異步下載,然后將下載的圖片緩存在內存和磁盤上 |
支持使用URL加載圖片 | 提供了便捷的API來從網絡上加載圖片,支持常見的圖片格式如JPEG、PNG、GIF等 |
自動管理圖片緩存 | SDWebImage會自動管理內存和磁盤緩存,可以設置最大內存緩存大小和最大磁盤緩存大小,并根據需要自動清理緩存 |
圖片加載進度回調 | 提供了加載進度回調的功能,可以監測圖片加載的進度 |
支持占位圖和失敗圖 | 可以設置占位圖,當圖片還在加載時顯示;同時還可以設置失敗圖,當加載圖片失敗時顯示 |
支持內存緩存和磁盤緩存控制 | 可以通過設置緩存策略和過期時間來控制內存緩存和磁盤緩存的行為 |
支持取消圖片下載任務 | 提供了取消圖片下載任務的方法,可以在需要時取消正在進行的圖片下載任務 |
集成了UIImageView的擴展方法 | 提供了方便的UIImageView擴展方法,可以直接加載網絡圖片到UIImageView對象中 |
支持自定義圖片加載和緩存策略 | 可以通過自定義SDWebImageManager來實現自定義的圖片加載和緩存策略 |
使用內存和磁盤緩存加速從磁盤快速顯示圖片 | 當從磁盤加載圖片時,SDWebImage會首先檢查內存緩存,如果內存中有緩存的圖片,則直接加載;如果內存中沒有,則從磁盤緩存中加載圖片 |