1

UIViewControllerはこのプロパティを含む を持っています:

@property (weak, nonatomic) IBOutlet UITableView *customerTableView;

UIViewController のviewDidLoadメソッドには、次のものがあります。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // ...
    CustomerTableViewDataSource *dataSource = [[CustomerTableViewDataSource alloc]
        init];
    [dataSource setData:customersSource];
    [customerTableView setDataSource:dataSource];
}

NSZombies を有効にしてこれを受け取ります:

*** -[CustomerTableViewDataSource numberOfSectionsInTableView:]: message sent to 
deallocated instance 0x3e07a0

割り当て解除されたインスタンス アドレスは、データ ソースと同じです。

データ ソースが「固定」されていない理由はありますか?

シミュレーターとゾンビを使用すると、参照が でリリースされていることがわかります。viewDidLoadこれは、そのメソッドで宣言したため、当然のことであり、範囲外になるはずですが、呼び出すsetDatasourceとrefctが増加すると思います。まあ、どうやらそうではありません。

この動作を変更する方法はありますか?

注: ivar を作成してデータ ソースを保存すればすべて機能しますが、クラスが乱雑になっているように感じます。これは都市での生活ですか?

4

2 に答える 2

3

ドキュメントからUITableView

@property(nonatomic、assign)id dataSource

討論

データソースはUITableViewDataSourceプロトコルを採用する必要があります。データソースは保持されません。

これはcustomerTableView、データソースオブジェクトを保持することを期待していることを意味しますが、これは保持していません。の代理人にも同じUITableViewことが言えます(実際、ココアのほとんどすべての代理人に当てはまります。ただし、の代理人は除きCALayerます)。この設計上の決定は、理由UITableViewがあります。非常に頻繁に保持するオブジェクトは、そのデリゲートとしても機能します。デリゲートが保持されていた場合、プログラマーは保持サイクルに対処する必要があります。

残念ながら、その決定の結果はあなたが抱えている問題です。たとえば、ivarを設定することによって、データソース(および存在する場合はデリゲート)を保持する必要があります。

于 2012-08-16T22:39:58.557 に答える
0

Apple が ARC を導入する前であっても、Table View のデータ ソースとデリゲート (ほぼすべてのデリゲートと同様に、設計上) は常に (保持) ではなく (割り当て) として宣言されていました。今日のARCの世界では、__weakと宣言されていると確信しています(そうでなければ、保持サイクルが発生します)。そうです、クラスでivarを作成してください - それはまさにivarの目的です。

P. s .: 一般に、「データ ソース」クラスと「デリゲート」クラスを別々に作成するのは不適切な設計です。物事が複雑にならない限り、常にビュー コントローラーをデリゲート/データ ソースとして使用することをお勧めします。 MVC、それはそれのために設計されたレイヤーです-ロジックをディスプレイにリンクする(ビュー)コントローラー。

于 2012-08-16T22:28:26.597 に答える