52個編寫高質量iOS有效方法(41-50)

倒計時回家還剩下兩天

1.在OC中如果有多個線程想使用同一份代碼,那么多線程讀寫可能會出現問題。這時候需要對某一個對象進行加鎖操作。@synchronized可以實現這種加鎖,但是效率非常低,同樣的NSLock與NSRecurisiveLock也是可以實現這種加鎖操作,但是效率不高。一種比較推崇的是GCD。下面是具體的實現代碼

_syncQueue = dispatch_get_global_create("DISPATCH_QUEUE_PRIORITY_DEFAULT",NULL);  
-(NSString*) someString {  
    __block NSString* localSomething;  
    dispatch_sync(_syncQueue,^{  
        localSomeString = _someString;  
    });  
    return localSomeString  
}  
-(void) setSomeString:(NSString*) someString{  
    dispatch_barrier_async(_syncQueue,^{  
        _someString = someString;  
    });  
} 

2.盡量少用performSeletor,因為這個方法可以添加的方法參數有限。而且performseletor再ARC環境下,內存管理方面有缺失。因此如果想使用這種動態綁定方法,可以選擇使用NSInvocation,自己封裝一個對象跟調用方法,然后進行消息轉發。如果想延遲幾秒調用一個函數注意下面的寫法:

不推薦:
[self performSelector:@selector(show) withObject:nil afterDelay:0.4];
推薦:
dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(0.4*NSEC_PER_SEC));
dispatch_after(time,dispatch_get_main_quene(),^(){[self show] });

如果想吧任務放在主線程上面,也可以選擇下面兩種方法:

不推薦: [self performSelectorOnMianThread:@selector(doSomething) withObject:nil waitUntilDone:No];
推薦:
dispatch_async(dispatch_get_main_quene(),^({self doSemthing}));

3.很少有其他技術能與gcd的同步機制相媲美。對于那些只需要執行一次的代碼來說,也是如此,使用gcd的dispatch_once最為方便。然而在執行后臺任務時候,gcd并不一定是最佳方式。還有一種技術叫做NSOpertationQueue,它雖然與gcd不同,但是卻與之相關,開發者可以把操作以NSOpertation子類的形式放到隊列中,這些操作也能夠并發執行。

在兩者差別中,首先要注意:gcd是純c的API,而操作隊列是OC對象。gcd處理輕量級block而操作隊列處理重量級OC對象。

用NSOperationQueue類的addOperatonWithBlock方法搭配NSBlockOperation類來操作隊列,其語法與純gcd方法非常類似。使用NSOperation和NSOpertaionQueue的好處如下:

● 取消某個操作

● 指定操作間的依賴關系

● 通過鍵值觀測機制監控NSOperation屬性。

● 指定操作的優先級

● 重用NSOperation對象。

操作隊列很多地方勝過派發隊列。操作隊列提供了很多執行任務的方法,而且都是寫好了,直接就能用。開發者不用再編寫復雜的調度器。

NSNotificationCenter使用了操作隊列

本節要點

● 在解決多線程與任務管理問題時,派發隊列并非唯一方案。

● 操作隊列提供了一套高層次的OC API。能實現純gcd所具備的絕大部分功能,而且還能完成一些更為復雜的操作,那些操作如果該用gcd來實現,則需要另外寫代碼。

4.簡單講了一下dispatch_group的用法,用來封裝一組操作。只有當這個組中所有的任務都執行完成之后會有一個通知,然后繼續做后面操作。

5.直接看代碼吧,通常是單例的實現。

+(id) sharedInstance{  
    static EOCClass *sharedInstance = nil;  
    static dispatch_once_t onceToken;  
dispatch_once(&onceToken,^{sharedInstance = [[self alloc]init];});  
return sharedInstance;  
}  

6.不要使用dispatch_get_current_queue 原因如下:

  • dispatch_get_current_queue 函數的行為通常與開發者的預期不一致,這個函數已經廢棄了,只做調試用。
  • 這個函數通常用來解決不可重入的代碼所引發的死鎖,然而如果可以用這個函數來解決的問題,通常也可以用特定的隊列來解決。

7.熟悉系統框架,并沒有講什么東西

8.只是作為一個建議,多用塊枚舉,少用for循環

9.上面提到過Foundation框架和CoreFoundation框架,Foundation中NSArray等collection,CoreFoundation中也有對應的CFArray,這兩種創建數組的方式也許有區別,然而“無縫橋接”技術可以使得這兩個類型之間平滑互轉。下面代碼演示了簡單的無縫橋接:

NSArray *anNSArray = @[@1,@2,@3,@4,@5];  
CFArrayRef aCFArray = (__bridge CFArrayRef)anNSArray;  
NSLog(@"size of array =%li",CFArrayGetCount(aCFArray)); 

__bridge本身的意思是:ARC仍然具備這個OC對象的所有權

10.構建緩存時選用NSCache而非NSDictionary
NSCache比NSDictonary好的地方是:當系統資源將要耗盡時,它可以自動刪減緩存(刪減“最近未使用的對象”)。下面這段代碼演示了緩存的用法:

#import <Foundation/Foundation.h>  
  
//network fetcher class  
typedef void(^EOCNetworkFetcherCompletionHandler)(NSData* data);  
@interface EOCNetworkFetcher : NSObject  
-(id)initWithURL(NSURL*)url;  
-(void)startWithCompletionHandler:(EOCNetworkFetcherCompletionHandle)handler;  
@end  
  
// class that uses the network fetcher and caches results  
@interface EOCClass :NSObject  
@end  
@implementation EOCClass{  
    NSCache* _cache;  
}  
-(id)init{  
    if(self = [super init]){  
        _cache = [NSCache new];  
        //cache a maximum of 100 URLs  
        _cache.countLimit = 100;  
        //the size in bytes of data is used as the cost,so this sets a cost limit of 5MB  
        _cache.totalCostLimit = 5*1024*1024;  
    }  
    return self;  
}  
-(void) downloadDataForUrl:(NSURL*)url{  
    NSData *cachedData = [_cache objectForKey:url];  
    if(cachedData){  
    //cached it  
    [self useData:cacheData];  
}else{  
    //cache miss  
    EOCNetworkFetcher* fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]  
    fetcher startWithCompletionHandler:^(NSData* data){  
        [_cache setObject:data forKey:url cost:data.length];  
        [self useData:data];  
        }];  
    }  
}  
@end  

創建NSCache時,將其中可緩存的對象數目設定為100,將“總開銷”上限設為5MB

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容