1忌栅、UITextField 和 UITextView 在 iOS7 下不能重寫 dealloc 方法
在 iOS7 的情況下曲稼,如果在 Category 重寫了 UITextField 或 UITextView 就會發(fā)生莫名其妙的崩潰問題。
得到崩潰的調(diào)用棧如下:
可以看出破衔,系統(tǒng)發(fā)出了一個通知钱烟,NSNotification,然后 Runloop 往 Observer 發(fā)送回調(diào)嫡丙,然后 UITextSelectionView 執(zhí)行 textSelectionViewActivated 的時候崩潰了拴袭。
很明顯在 iOS7 的情況下,iOS 系統(tǒng)默認會在 UITextField 和 UITextView 的 dealloc 方法下去釋放一些通知方法曙博,減少 Observer拥刻。所以上面我重寫了 dealloc 方法,在 iOS7 下不會去釋放通知父泳,導(dǎo)致 Runloop 發(fā)送了 通知方法的時候找不到對象般哼,從而野指針崩潰。
iOS系統(tǒng)使用第三方鍵盤收到三次 UIKeyboardWillShowNotification 通知
使用搜狗鍵盤惠窄,確實引起了不必要的麻煩蒸眠,哎,但是 UIKeyboardWillHideNotification 卻只會出現(xiàn)一次杆融,Lucky。
解決方法:
NSDictionary* dict = [aNotification userInfo];
CGRect endKeyboardFrame = [[dict objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect beginKeyboardFrame = [[dict objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
/**
abson issu1: iOS使用第三方鍵盤的情況下池摧,收到三次鍵盤通知,傻B iOS 系統(tǒng)
*/
if (isShowKeyBoard ) {
if (false == (fitBeginKeyBoardFrame.size.height > 0 && fitBeginKeyBoardFrame.origin.y - fitEndKeyBoardFrame.origin.y)) {
return;
}
}
iOS7的情況下宦棺,如果鍵盤還在顯示的時候成黄,旋轉(zhuǎn)屏幕央拖,系統(tǒng)會分別很快的發(fā)出 UIKeyboardWillHideNotification饶唤、UIKeyboardWillShowNotification 這兩個通知。
使用鍵盤的時候注意旋轉(zhuǎn)屏幕出現(xiàn)的這個惡心bug欣尼,如果不少心在 UIKeyboardWillHideNotification 的時候做動畫,并在動畫結(jié)束時執(zhí)行某些動做,例如如下:
那么就會有一個問題,因為系統(tǒng)很快就發(fā)出了 UIKeyboardWillShowNotification 這個通知册着,但是上圖的 manageViewPositionForKeyBoard:
這個方法卻被 0.25秒后執(zhí)行了鞭执,而界面卻沒有發(fā)生變化大溜,從而導(dǎo)致數(shù)據(jù)錯亂的問題。
解決方法:加上一個屬性判斷動畫是否執(zhí)行中朦拖,如果 UIKeyboardWillShowNotification 引發(fā)的動畫在執(zhí)行中,那么睬隶,即使 0.25 秒后也不能讓他執(zhí)行 completion:
這個 block。
iOS7 下兩次錄音會導(dǎo)致 record 方法返回 false
_audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];
_audioRecorder.delegate = self;
if ([_audioRecorder prepareToRecord] == YES){
sleep(0);
BOOL result = [_audioRecorder record];
_isRecording = result;
}
如果上面代碼不添加 sleep(0)
, 就會導(dǎo)致 iOS7 [_audioRecorder record]
第二次創(chuàng)建的時候返回false贰锁。
sleep(0)
的作用:
Sleep(n)的作用是讓當前線程睡眠n毫秒,以便執(zhí)行其他線程,如果沒有其他線程芯肤,那睡眠n毫秒后油吭,繼續(xù)執(zhí)行歌豺。
而如果n=0,Sleep(0)
是指CPU交出當前線程的執(zhí)行權(quán),讓CPU去執(zhí)行其他線程萧锉。也就是放棄當前線程的時間片鲫凶,轉(zhuǎn)而執(zhí)行其他線程。
一般來說掸屡,如果當前線程比較耗時比較占CPU資源仅财,可以在結(jié)尾處加上Sleep(0)
, 這樣效率會得到大大的提高碎罚。
另外,還可以用這種方法來保證線程同步耙考,線城池工作時,主線程使用Sleep(0)
來等待線程池里所有的線程都完成運行。當線程池線程非常多的時候,這種方法確實是一種非常有效的節(jié)省 cpu 的方式,因為它節(jié)省了在線程里使用內(nèi)核來進行同步的開銷。
對比上面:
由于 [_audioRecorder prepareToRecord]
為給錄音分配資源的api,包括內(nèi)部線程池分配資源等,所以,加上 Sleep(0)
目的在于等待其線程池資源分配成功磨隘。
iOS 的文件路徑保存數(shù)據(jù)庫不可保存全路徑
[[NSUserDefaults standardUserDefaults] setObject:filePath forKey:SocialAudioDataBase];
上面這句話中,如果 filePath 為 /var/mobile/Containers/Data/Application/A07505E5-9A3B-4CF2-B424-738294B1589F/Documents/94538510998/audio/94538510998/3351b914c4c937134c0f57efbc2dcb1b.wav
這樣的全路徑,下次取出 filePath 的時候,使用
bool result = [[NSFileManager defaultManager] fileExistsAtPath:audioPath]
result
會返回false。因為每次應(yīng)用運行的 Application/A07505E5-9A3B-4CF2-B424-738294B1589F
這個路徑都在改變。所以保存路徑不能保存全路徑,只能保存 Documents
文件夾后的部分路徑井辜,下次使用的時候刷允,再使用
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsFilePath = [paths lastObject];
NSString* fullPath = [documentsFilePath stringByAppendingPathComponent:savePath];
這樣去拼接得到全路徑路徑。
未完待續(xù)....