iOS資料 介面分開設計模式遇到的乙個問題

2021-06-09 12:31:45 字數 3121 閱讀 1989

我們習慣在開發中把資料和介面分開實現,這種方式比較好,只需要在資料和介面中同時依賴乙個資料結構即可,這種做法對於解藕是乙個不錯的方式。

但是有一些細節的地方可能會導致我們遇到一些很難查詢的bug,比如我們之前遇到的乙個問題,現在分享給大家。

先來描述一下問題:我們在uitableview中加入了乙個向下拖動重新整理資料的控制項,控制項是egorefreshtableheaderview。拖動後,我們就使用asihttprequest重新整理資料,但是在拖動幅度大一些時,asihttprequest請求發出後就直接崩潰了,而且看棧也看不出崩在哪。

資料請求**如下:

- (void)startgetnewslistdata

nsstring *strurl = @"*****";//此處需要填入url的位址字串

//設定委託,委託自己實現非同步請求方法

[request setdelegate : self ];

// 開始非同步請求

[requeststartasynchronous ];//執行完這句後,就直接崩潰了

......//其他邏輯

[[nsnotificationcenterdefaultcenter]postnotificationname:@"getnewslistdatadone"object:newsdataarray];

}

猜測除錯過程如下:

1)開始猜測問題是egorefreshtableheaderview大幅拖動導致的,於是把asihttprequest請求資料注釋掉,再次大幅拖動,程式沒崩。

2)那問題一定出在

asihttprequest請求部分,猜測會不會是請求在子執行緒中做的,導致的問題,除錯一下,發現請求還是在主線程中,所以也排除了這種情況。

3)一開始一直以為是

asihttprequest出的問題,所以精力一直放在他上面。但是後來調了1個小時,查了asihttprequest的使用說明,也沒查到什麼疑點。

4)實在是沒辦法了,祭出屠龍寶刀:開始**分段注釋,執行看結果。問題出在

- (void)startgetnewslistdata函式,所以從這邊開始:注釋

if (nil != newsdataarray && newsdataarray.count > 0)

這段,執行,結果正常了,http請求也能收到返回的結果了,天哪,要是早點採用這種方法,也就不用之前嘗試的1個小時了。開始分析為什麼,

newsdataarray

前面說了,這個資料是會通過

[[nsnotificationcenter defaultcenter] postnotificationname:@"getnewslistdatadone" object:newsdataarray]; 傳送,給uitableview中使用,看接收稱處的**:

......

[[nsnotificationcenterdefaultcenter]addobserver:selfselector:@selector(ongetnewslistdatasuccess:)name:@"getnewslistdatadone"object:nil];

......

- (void)ongetnewslistdatasuccess:(nsnotification*)notify

[m_tableview reloaddata];

......

}- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath

nsinteger row = indexpath.row;

if (m_arrnews)

......

return cell;

}

看完這些,我也知道問題出在什麼地方了,我們知道,在uitableview中,在使用者拖動cell,有cell 的indexpath發生變化時,就會觸發這個函式:

- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)這個函式中我們用到了m_arrnews,而m_arrnews又是通過

nsmutablearray *receivearray = [notify object];

......

m_arrnews = receivearray;

這麼來的,這裡面全是使用的指標拷貝,原來問題就是這個:淺拷貝,

先來解釋一下深拷貝和淺拷貝:

(1)深拷貝,就是新拷貝一塊記憶體交給物件使用。會拷貝整個資料到新的位址,老的拷貝源改變和目標位址的資料就無關了。

(2)淺拷貝,就是覺得拷貝記憶體太浪費,直接給你我的位址吧。當然這個位址和拷貝源相同,只要拷貝源發生改變,這個目標位址中的資料也會變化。

問題就明顯了

[newsdataarray

removeallobjects

];導致了uitableview中的資料來源發生變化,而大幅度拉動,導致了uitableview中資料重新整理,進入

- (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *),資料失效,導致崩潰,那解決問題也很簡單,使用深拷貝就可以了。

- (void)ongetnewslistdatasuccess:(nsnotification*)notify

[m_tableviewreloaddata];

......

}

問題解決,收工。

問乙個系統設計的問題

當使用hibernate開源框架去做乙個大中型系統的持久層時,我們一開始做的究竟應該是先設計資料庫,然後按照資料庫,使用工具將資料庫對映成物件 還是完全撇開傳統的關聯式資料庫思想,先建立實體之間關係圖 或建立域模型 然後根據該模型在設計資料庫。不知道大家在平時的設計時一般按哪樣的流程去做,能否介紹下...

MFC寫的乙個介面遇到的問題

1 變數值從一父視窗類傳遞到子視窗類中。方法 cmplayer wnew wnew.buf1 buffer wnew.domodal 2 vs2012中工程預設為unicode字符集,所以使用的實際上是cstringw類。a cstring轉換為char陣列要想使用getbuffer和strcpy轉...

如何設計乙個良好的介面

在設計介面時,有很多因素要考慮,如介面的業務定位,介面的安全性,介面的可擴充套件性 介面的穩定性 介面的跨域性 介面的協議規則 介面的路徑規則 介面單一原則 介面過濾和介面組合等諸多因素,本篇文章將簡要分析這些因素。一 規範性建議 1.職責原則 在設計介面時,必須明確介面的職責,即介面型別,介面應解...