前言
昨天加班,本來順順利利的,后來測試拿了一個6P來測,裝的是8.4.1的系統,我心說真牛,這么老的系統還留著,測試說,就怕有些用戶不更新,就喜歡這個版本.本來也沒有什么大不了,可沒想到測出來的BUG讓我嚇了一跳,特此記錄一下.
- 1.在8.4.1版本上側滑沒有出現刪除按鈕
- 2.在8.4.1版本上側滑之后返回上個界面pop的時候程序閃退(注:進入需要刪除的界面之后,如果對表格沒有點擊操作,沒有右滑刪除操作,返回上個界面是沒有崩潰的,??,其實這里應該看出來的)
一,首先在最新的版本iOS11上沒有出現此類情況,在其他版本應該也沒有出現此類情況,不然測試就找我了.
我首先查看了我調用的API是否在iOS8中有沒有,
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1)//new
{
return YES;
}
return NO;
}
-(nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{}
NS_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED
這個API注明iOS8以后可以使用,在watchOS 中禁用.按道理來說應該沒錯,但是沒有道理可講,在8上側滑沒有反應.然后我就查了一下,大佬們說這是因為什么balabala,加上
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{}
加上這段代碼,什么都不用寫,然后就可以了.我試了一下,居然真的可以,真是石樂志.(應該是iOS8中在低版本會先調用這個方法,然后再去走新的方法,不懂)
二,這個Bug就比較雞賊了,閃退的時候沒有崩潰的提示信息,直接到了 main 函數里,搜索的時候,看到大佬說的話,一般直接跳到main函數里的并且不打印任何日志的崩潰應該和內存有關系.謝謝
對了,因為覺得API會影響,所以我把
-(nullable NSArray<UITableViewRowAction *> *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath{}
注釋了,實現了
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle ==UITableViewCellEditingStyleDelete) {
[self removeAction:indexPath.row];//這個方法進行刪除數組元素,刷新列表的操作
}
}
接下來要做的事情,通過xcode自帶的僵尸方法,檢查,怎么打開呢,
請按著command+shift+< ,看截圖
第二個方法,開著比不開強,我覺得 可以追蹤內存來源
保存后,重新運行程序,再重復之前的操作,bug 出現了,右下角也有打印出日志了,問題如下:
2017-12-25 10:13:05.194 xx寶[1621:124805] *** -[STrustDeviceManagerViewController tableView:canEditRowAtIndexPath:]: message sent to deallocated instance 0x158aedfc0
搜索之后發現,有人早在幾年前就遇到了這個問題,一下內容大部分為原文來自
startong的博客
也就是說,tableView:canEditRowAtIndexPath 這個方法有問題,那我就納悶兒了,這個方法怎么可能會有問題,難怪我之前注釋掉了這個方法就沒問題了,果然是這里有問題,知道了問題針對它解決掉也就不會是什么難事兒了,我初步懷疑是 return YES 的問題,
于是,我在函數里加了這樣幾行代碼
-
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.bgTableView setEditing:NO];
}
然后再重新運行,重復之前的操作,問題解決了,perfect,,,,
雖然問題解決了,但是還是覺得,canEditRowAtIndex 這個方法應該不會有問題,于是我再 ios 6 的模擬器下運行程序,重復操作沒問題(當然注釋掉viewWillDisappear 方法),后來到網上找了好多資料,很大神都說可能是蘋果自身的問題,ios7 才有這個問題,ios6 以及以下不會出現這種問題,
至此,問題得到解決,以上列出了兩種解決方案:
1,刪掉canEditRowAtIndexPath這個方法不用,不會出問題;(PS : 這個不行,我的表格里面第二個區,才能進行刪除操作,而且里面還有一行不能刪除,這個方法可以用,但是要看你的實際需求了.)
2,加上上面說的 viewWillDisappear 方法也可以解決問題;但是我個人推薦第二種方法,雖然第一種方法也是可以解決問題的,但是個人還是覺得這兩個方法配套使用比較好。
最終總結
最終總結出問題 可能是在 canEditRowAtIndexPath 這個方法里設置了YES然后返回的時候沒有把它設置成 NO 所以報錯,ios6會自動設置成NO,iOS7 就手動設置成 NO也可以。所以以后無論什么版本,我們都加上viewWillDisappear手動設置 editing 這個屬性為NO 這樣確保萬無一失。
插一句,在iOS9以上沒有這個問題,估計是蘋果也處理了這個問題,在界面釋放的時候,自動設置為NO,所以能升級就趕緊升級,不要讓程序猿痛苦了.
如果對你有用,請為我點個贊,留個念.謝謝了