4

UITableView がセットアップ中にデリゲートとデータソースを何度も繰り返し呼び出す理由を明らかにしたい人はいますか? 私が現在取り組んでいるものを見るだけで、それnumberOfSectionsInTableViewが3回呼び出され、viewForHeaderInSectionセクションでさらに3回循環することがわかります(2つのセクションがあるため、最初に表示される前に合計6回)...すべて最初の画面もレンダリングされます。

API が非公開であることは認識していますが、誰かがこの設計パターンと舞台裏で何起こっているのかについての洞察を喜んで提供してくれるのではないかと考えています。さらに有利です) この場合...または、おそらく、私がどのようにそれを適用して失敗したか.

編集: RootViewController tableView が初めて表示される前にスタック トレースを追加しました

初めてviewForHeaderInSectionを呼び出す:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c901a8 in -[UITableView(UITableViewInternal) _delegateWantsHeaderForSection:]
#2  0x30c8f6f4 in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
#3  0x30c8f5a8 in -[UITableViewRowData rectForFooterInSection:]
#4  0x30c3d430 in -[UITableViewRowData heightForTable]
#5  0x30c05430 in -[UITableView(_UITableViewPrivate) _updateContentSize]
#6  0x30c3ce0c in -[UITableView noteNumberOfRowsChanged]
#7  0x30c3c7c0 in -[UITableView reloadData]
#8  0x30e50e60 in -[UITableViewController viewWillAppear:]
#9  0x30c78810 in -[UINavigationController _startTransition:fromViewController:toViewController:]
#10 0x30c783b0 in -[UINavigationController _startDeferredTransitionIfNeeded]
#11 0x30c782a0 in -[UINavigationController viewWillLayoutSubviews]
#12 0x30c5c874 in -[UILayoutContainerView layoutSubviews]
#13 0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#14 0x33e871c0 in -[CALayer layoutSublayers]
#15 0x33e86edc in CALayerLayoutIfNeeded
#16 0x33e86844 in CA::Context::commit_transaction
#17 0x33e86474 in CA::Transaction::commit
#18 0x33e8e5dc in CA::Transaction::observer_callback
#19 0x32d5c830 in __CFRunLoopDoObservers
#20 0x32da4346 in CFRunLoopRunSpecific
#21 0x32da3c1e in CFRunLoopRunInMode
#22 0x31bb9374 in GSEventRunModal
#23 0x30bf3c30 in -[UIApplication _run]
#24 0x30bf2230 in UIApplicationMain
#25 0x00002260 in main at main.m:14

2 回目の呼び出し:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c901a8 in -[UITableView(UITableViewInternal) _delegateWantsHeaderForSection:]
#2  0x30c8f6f4 in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
#3  0x30c90628 in -[UITableViewRowData(UITableViewRowDataPrivate) _ensureSectionOffsetIsValidForSection:]
#4  0x30c8f5d0 in -[UITableViewRowData rectForFooterInSection:]
#5  0x30c3d430 in -[UITableViewRowData heightForTable]
#6  0x30c05430 in -[UITableView(_UITableViewPrivate) _updateContentSize]
#7  0x30c3ce0c in -[UITableView noteNumberOfRowsChanged]
#8  0x30c3c7c0 in -[UITableView reloadData]
#9  0x30e50e60 in -[UITableViewController viewWillAppear:]
#10 0x30c78810 in -[UINavigationController _startTransition:fromViewController:toViewController:]
#11 0x30c783b0 in -[UINavigationController _startDeferredTransitionIfNeeded]
#12 0x30c782a0 in -[UINavigationController viewWillLayoutSubviews]
#13 0x30c5c874 in -[UILayoutContainerView layoutSubviews]
#14 0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#15 0x33e871c0 in -[CALayer layoutSublayers]
#16 0x33e86edc in CALayerLayoutIfNeeded
#17 0x33e86844 in CA::Context::commit_transaction
#18 0x33e86474 in CA::Transaction::commit
#19 0x33e8e5dc in CA::Transaction::observer_callback
#20 0x32d5c830 in __CFRunLoopDoObservers
#21 0x32da4346 in CFRunLoopRunSpecific
#22 0x32da3c1e in CFRunLoopRunInMode
#23 0x31bb9374 in GSEventRunModal
#24 0x30bf3c30 in -[UIApplication _run]
#25 0x30bf2230 in UIApplicationMain
#26 0x00002260 in main at main.m:14

3 回目の呼び出し:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c901a8 in -[UITableView(UITableViewInternal) _delegateWantsHeaderForSection:]
#2  0x30c3eebc in -[UITableView(_UITableViewPrivate) _updateVisibleHeadersAndFootersNow]
#3  0x30c3e578 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow]
#4  0x30c3c514 in -[UITableView layoutSubviews]
#5  0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#6  0x33e871c0 in -[CALayer layoutSublayers]
#7  0x33e86edc in CALayerLayoutIfNeeded
#8  0x33e86844 in CA::Context::commit_transaction
#9  0x33e86474 in CA::Transaction::commit
#10 0x33e8e5dc in CA::Transaction::observer_callback
#11 0x32d5c830 in __CFRunLoopDoObservers
#12 0x32da4346 in CFRunLoopRunSpecific
#13 0x32da3c1e in CFRunLoopRunInMode
#14 0x31bb9374 in GSEventRunModal
#15 0x30bf3c30 in -[UIApplication _run]
#16 0x30bf2230 in UIApplicationMain
#17 0x00002260 in main at main.m:14

4 回目の呼び出し:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c9712c in -[UITableView(UITableViewInternal) _sectionHeaderViewWithFrame:forSection:opaque:reuseViewIfPossible:]
#2  0x30c3f0b4 in -[UITableView(_UITableViewPrivate) _updateVisibleHeadersAndFootersNow]
#3  0x30c3e578 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow]
#4  0x30c3c514 in -[UITableView layoutSubviews]
#5  0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#6  0x33e871c0 in -[CALayer layoutSublayers]
#7  0x33e86edc in CALayerLayoutIfNeeded
#8  0x33e86844 in CA::Context::commit_transaction
#9  0x33e86474 in CA::Transaction::commit
#10 0x33e8e5dc in CA::Transaction::observer_callback
#11 0x32d5c830 in __CFRunLoopDoObservers
#12 0x32da4346 in CFRunLoopRunSpecific
#13 0x32da3c1e in CFRunLoopRunInMode
#14 0x31bb9374 in GSEventRunModal
#15 0x30bf3c30 in -[UIApplication _run]
#16 0x30bf2230 in UIApplicationMain
#17 0x00002260 in main at main.m:14

5 回目の呼び出し:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c901a8 in -[UITableView(UITableViewInternal) _delegateWantsHeaderForSection:]
#2  0x30c3eebc in -[UITableView(_UITableViewPrivate) _updateVisibleHeadersAndFootersNow]
#3  0x30c3e578 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow]
#4  0x30c3c514 in -[UITableView layoutSubviews]
#5  0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#6  0x33e871c0 in -[CALayer layoutSublayers]
#7  0x33e86edc in CALayerLayoutIfNeeded
#8  0x33e86844 in CA::Context::commit_transaction
#9  0x33e86474 in CA::Transaction::commit
#10 0x33e8e5dc in CA::Transaction::observer_callback
#11 0x32d5c830 in __CFRunLoopDoObservers
#12 0x32da4346 in CFRunLoopRunSpecific
#13 0x32da3c1e in CFRunLoopRunInMode
#14 0x31bb9374 in GSEventRunModal
#15 0x30bf3c30 in -[UIApplication _run]
#16 0x30bf2230 in UIApplicationMain
#17 0x00002260 in main at main.m:14

6 回目の呼び出し:

#0  0x000086cc in -[RootViewController tableView:viewForHeaderInSection:] at RootViewController.m:444
#1  0x30c9712c in -[UITableView(UITableViewInternal) _sectionHeaderViewWithFrame:forSection:opaque:reuseViewIfPossible:]
#2  0x30c3f0b4 in -[UITableView(_UITableViewPrivate) _updateVisibleHeadersAndFootersNow]
#3  0x30c3e578 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow]
#4  0x30c3c514 in -[UITableView layoutSubviews]
#5  0x30c382d8 in -[UIView(CALayerDelegate) _layoutSublayersOfLayer:]
#6  0x33e871c0 in -[CALayer layoutSublayers]
#7  0x33e86edc in CALayerLayoutIfNeeded
#8  0x33e86844 in CA::Context::commit_transaction
#9  0x33e86474 in CA::Transaction::commit
#10 0x33e8e5dc in CA::Transaction::observer_callback
#11 0x32d5c830 in __CFRunLoopDoObservers
#12 0x32da4346 in CFRunLoopRunSpecific
#13 0x32da3c1e in CFRunLoopRunInMode
#14 0x31bb9374 in GSEventRunModal
#15 0x30bf3c30 in -[UIApplication _run]
#16 0x30bf2230 in UIApplicationMain
#17 0x00002260 in main at main.m:14
4

2 に答える 2

1

私のコードnumberOfSectionsInTableViewでは、呼び出しに応じて一度だけ呼び出されreloadDataます。

ブレークポイントを設定numberOfSectionsInTableViewし、コール スタックを調べて、それがどのように、なぜ呼び出されているかを確認できます。

于 2009-12-17T00:49:08.073 に答える
0

それらを頻繁に呼び出す理由の1つは、[... reloadData]などがあるたびに状況が劇的に変化する可能性があるため、前回呼び出したときの状態であるとは想定できないためです。UITableViewCellsこれが、たとえばドキュメントのキャッシュを大いに活用する理由の1つです。

これを示すクラスは次のとおりです。

@interface WinnersViewController : UITableViewController {
}
- (void)setDataSourceAndDelegate;
@end

setDataSourceAndDelegate私のviewDidLoadで、 3つのクラスの1つをデータソースとして設定し、テーブルビューのプロパティを委任するというメソッドを呼び出します。

- (void)viewDidLoad {
    [self setDataSourceAndDelegate];
    [super viewDidLoad];
}

使用するDataSourceおよびDelegate(組み合わせ)として機能する3つの異なるオブジェクトがあり、その上に抽象クラスがあります。

WinnersViewDefaultDSD
WinnersViewHasLocationDSD
WinnersViewHasExampleDSD

(明らかな理由で、問題の実際のクラス名をExampleに置き換えました。)

これらのクラスはテーブルビューに非常に異なるものを返します。アプリケーションの状態が変わると(CoreLocationを呼び出したり、ユーザーがクラスの例のインスタンスを選択したりした場合など)、setDataSourceAndDelegateメソッドが再度呼び出され、どのオブジェクトであるかを変更できます。急いで。

したがって、UITableViewがデリゲートとデータソースで非常に多くのことを何度も呼び出す理由は、テーブルビューでこの種のことを行う開発者をサポートする必要があるためです。特定のメソッドが一度呼び出された後、答えが変わらないと想定された場合、それはそれほど柔軟ではありません。

とにかく、これが役立つ例であることを願っています。

(ああ、誰かがこれをエミュレートしようとしている場合は、TableViewのデリゲートとデータソースのプロパティがコピーされて保持されないことに注意してください。DSDクラスのインスタンスで追加の保持を行う必要があります。そうしないと、不思議になりますが頻繁にクラッシュします。)

(また、さまざまなDSDサブクラスのviewDidAppearをオーバーライドする必要があり、最終的にこれを行う必要がありました:)

- (void)viewDidAppear:(BOOL)animated
{
    [[(UITableView*)self.view delegate] delegatedViewDidAppear];
}

(これは、クラス内のDSDオブジェクトを追跡する必要がないようにするちょっとしたハックです。)

于 2010-02-06T22:48:49.200 に答える