我目前正在iOS6專用應用程序中實現自動狀態保存/恢復。對modelIdentifierForElementAtIndexPath的奇怪調用:inView:(UIDataSourceModelAssociation)
對於表視圖的恢復,我添加UIDataSourceModelAssociation
協議到我的表視圖控制器和實施
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
和
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
當按下家庭按鈕時,狀態保存方法(包括modelIdentifierForElementAtIndexPath:iView:
)正按預期方式調用,並返回給定索引路徑的有效標識符字符串。
當殺死應用程序並重新啓動它時,狀態恢復或多或少地起作用。即該應用程序重新打開正確的表格視圖。但是,表格視圖始終滾動到頂部,即使滾動到另一個位置之前。
下面是我的表視圖控制器中的UIDataSourceModelAssociation
方法的實現。沒有什麼幻想,在那裏往前走(的NdlFriend::accountUid
屬性返回給定NdlFriend記錄的唯一標識符字符串):
#pragma mark - UIDataSourceModelAssociation
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view
{
NSString* identifier = nil;
NSArray* content = self.contentArray;
// Sometimes idx might be nil...
if(idx && idx.row<content.count)
{
NdlFriend* friend = content[idx.row];
identifier=friend.accountUid;
}
return identifier;
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
{
NSIndexPath * indexPath=nil;
NSArray* content = self.contentArray;
NSInteger count = content.count;
for(NSInteger i=0;i<count;i++)
{
NdlFriend* friend = content[i];
if([identifier isEqualToString:friend.accountUid])
{
indexPath = [NSIndexPath indexPathForRow:i inSection:0];
break;
}
}
return indexPath;
}
我設置這兩種方法突破點。
爲了測試方法,我打開了表格視圖並向下滾動了一下。然後,當按下主頁按鈕時:
modelIdentifierForElementAtIndexPath:inView:
被調用一次,最上面可見行的索引路徑。該方法爲該行返回正確的uid。
到目前爲止好。
然後我停下來重新啓動應用程序。這裏是發生了什麼(我特別是第一次打破發點疑惑):
modelIdentifierForElementAtIndexPath:inView:
被調用,以nil
作爲索引路徑(視圖參數包含表視圖的正確的指針)。indexPathForElementWithModelIdentifier:inView:
被一個有效的標識符字符串調用(並且該方法返回一個有效的索引路徑)。indexPathForElementWithModelIdentifier:inView:
被再次調用(使用相同的標識符字符串)。- 表格視圖刷新,但滾動到最頂端。
有人知道,爲什麼滾動位置的恢復失敗? modelIdentifierForElementAtIndexPath:inView:
與nil
作爲indexPath可能與它有什麼關係(或者這是正常行爲)。
儘管表格視圖滾動位置(大部分)的恢復現在在iOS 9中起作用,但在空表視圖有時會出現'modelIdentifierForElementAtIndexPath:inView:'_gets調用的問題恢復,導致_bad訪問異常。解決方法是將方法簽名更改爲接受可壓縮的'NSIndexPath!',並防止'nil'(通過返回'nil'),即使它不應該發生**! (或者,爲了避免警告,如果'numberOfRowsInSection(0)'爲零,則返回'nil'也是可行的。) – penfold