啟示
第三方庫中經常用到的這個小技巧,例如YYCache,SDWebImage等等,雖然各自封裝的具體形式不太一樣。
- YYCache
- SDWebImage
- YYWebImage
我們可以借鑒到自己的項目中弃理,在適當的位置通過宏來加鎖解鎖操作。
使用
- 1.YYCache版本的宏封裝
#define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER)
#define Unlock() dispatch_semaphore_signal(self->_lock)
- 操作數據之前屎蜓,先外面進行加鎖解鎖
- (NSInteger)totalCount {
Lock();
int count = [_kv getItemsCount];
Unlock();
return count;
}
- 鎖里面再進行真正的數據操作
- (int)getItemsCount {
return [self _dbGetTotalItemCount];
}
2.SDWebImage版本的宏封裝
- 定義
#define LOCK(lock) dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
#define UNLOCK(lock) dispatch_semaphore_signal(lock);
- 調用示例
- (void)setValue:(nullable NSString *)value forHTTPHeaderField:(nullable NSString *)field {
LOCK(self.headersLock);
if (value) {
self.HTTPHeaders[field] = value;
} else {
[self.HTTPHeaders removeObjectForKey:field];
}
UNLOCK(self.headersLock);
}
其中痘昌,self.headersLock
的定義為:
@property (strong, nonatomic, nonnull) dispatch_semaphore_t headersLock;
3. YYWebImage版本的宏封裝
相對于上面,還有更方便的宏封裝炬转,把解鎖操作跟加鎖封裝在一塊辆苔。
- 宏定義
#define LOCK(...) dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(self->_lock);
#define LOCK_VIEW(...) dispatch_semaphore_wait(view->_lock, DISPATCH_TIME_FOREVER); \
__VA_ARGS__; \
dispatch_semaphore_signal(view->_lock);
- 使用示例
- (void)didReceiveMemoryWarning:(NSNotification *)notification {
[_requestQueue cancelAllOperations];
[_requestQueue addOperationWithBlock: ^{
_incrBufferCount = -60 - (int)(arc4random() % 120); // about 1~3 seconds to grow back..
NSNumber *next = @((_curIndex + 1) % _totalFrameCount);
LOCK(
NSArray * keys = _buffer.allKeys;
for (NSNumber * key in keys) {
if (![key isEqualToNumber:next]) { // keep the next frame for smoothly animation
[_buffer removeObjectForKey:key];
}
}
)//LOCK
}];
}