1、FMDB
FMDatabase:是一個提供 SQLite 數(shù)據(jù)庫的類,用于執(zhí)行 SQL 語句。
FMResultSet:用在 FMDatabase 中執(zhí)行查詢的結(jié)果的類。
FMDatabaseQueue:在多線程下查詢和更新數(shù)據(jù)庫用到的類。
/* 創(chuàng)建隊列,打開數(shù)據(jù)庫
* dbFilepath:數(shù)據(jù)庫路徑
* dbQueue:類實例
*/
FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbFilepath];
/* 操作數(shù)據(jù)庫
* sql:SQLite語法
* FMResultSet:返回查詢的結(jié)果
* -executeUpdate: 方法的參數(shù)都必須是對象 eg:[NSNumber numberWithInt:42]
*/
[dbQueue inDatabase:^(FMDatabase *db) {
// 查詢數(shù)據(jù)庫
FMResultSet *rs = [db executeQuery:sql];
if([rs next]){ // 查詢到數(shù)據(jù)
// 更新數(shù)據(jù)庫(是否成功)
BOOL bool = [db executeUpdate:sql];
}
}];
// 關(guān)閉數(shù)據(jù)庫
[dbQueue close];
FMDatabase 這個類是線程不安全的,在多線程中使用 FMDatabase 單例是極其錯誤的想法。不能在多線程的環(huán)境中對數(shù)據(jù)庫 FMDatabase 進(jìn)行讀寫,會出現(xiàn)奔潰或者異常,因為你不能保證你讀數(shù)據(jù)的同時另外一條線程不在寫數(shù)據(jù),F(xiàn)MDatabaseQueue 跨線程使用是同步的
2、dispatch_group
// 1、創(chuàng)建一個group
dispatch_group_t dispatchGroup = dispatch_group_create();
// 2、把一個異步操作加入到group中
dispatch_group_enter(dispatchGroup);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"startLocationCity");
// 2、把這個異步操作從group中移出
dispatch_group_leave(dispatchGroup);
});
// 3、阻礙線程。等待任務(wù)執(zhí)行在設(shè)置時間內(nèi)完成,或者超時,就會繼續(xù)執(zhí)行后面的操作
dispatch_group_wait(dispatchGroup, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC));
/* 4、等待dispatchGroup完成所有異步操作,但不會阻礙線程
* 適用與多個異步操作,得到多個結(jié)果,然后在一個地方完成操作
* eg:A,B異步操作,不分順序,但需要得到A,B的結(jié)果后再執(zhí)行C
*/
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
});
- dispatch_group_enter與dispatch_group_leave必須成對出現(xiàn)
- dispatch_group_enter:增加當(dāng)前group執(zhí)行block數(shù)
- dispatch_group_leave:減少當(dāng)前group執(zhí)行block數(shù)
dispatch_group_notify與dispatch_barrier_sync效果類似,區(qū)別在于一個異步,一個同步。
3、 NSCondition
NSCondition 的對象實際上作為一個鎖和一個線程檢查器:鎖主要為了當(dāng)檢測條件時保護(hù)數(shù)據(jù)源,執(zhí)行條件引發(fā)的任務(wù);線程檢查器主要是根據(jù)條件決定是否繼續(xù)運行線程,即線程是否被阻塞。
// 實現(xiàn)多線程的同步,即,可實現(xiàn)生產(chǎn)者消費者問題
NSConditon *condition =[ [NSCondition alloc]]init;
[condition lock];// 加鎖
[condition unlock];//與lock 同時使用,釋放鎖
[condition wait];//讓當(dāng)前線程處于等待狀態(tài)
[condition signal];//CPU發(fā)信號告訴線程不用在等待,可以繼續(xù)執(zhí)行,與wait對應(yīng)使用
4、 NSArray的排序
var array = ["M","O","H","R","L","W"]
// 1、倒敘
array = array.reversed() // ["W", "L", "R", "H", "O", "M"]
同oc:[[array reverseObjectEnumerator] allObjects];
// 2、升序
array = array.sorted() // ["H", "L", "M", "O", "R", "W"]
同oc:[array sortedArrayUsingSelector:@selector(compare:)];
// 3、降序(先sorted,再reversed,就等于降序)
array = array.reversed() // ["W", "R", "O", "M", "L", "H"]
注意:因為NSDictionary沒有排序,網(wǎng)絡(luò)請求有時候需要我們對其排序,我們可以通過NSArray的排序來完成
- (NSString *)transformedParams:(NSDictionary *)params
{
if ([params count]==0) {
return nil;
}
NSArray *keys = [params allKeys];
NSArray *sortedKeys = [keys sortedArrayUsingSelector:@selector(compare:)];
NSMutableString *paramString = [[NSMutableString alloc] init];
[sortedKeys enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) {
// value轉(zhuǎn)字符串
id value = [params objectForKey:key];
if (![value isKindOfClass:[NSString class]]) {
value = [NSString stringWithFormat:@"%@", value];
}
if ([value length] > 0) {
// 拼接字符串
if (idx==0) {
[paramString appendFormat:@"%@=%@",key,value];
}else{
[paramString appendFormat:@"&%@=%@",key,value];
}
}
}];
return paramString;
}