1

コメントアウトした以下の行で問題が発生する理由を説明してください。

それは、outlineView:objectValueForTableColumn:byItem: で EXC_BAD_ACCESS を引き起こしています。

完全なクラスの要点は、https ://gist.github.com/onato/9d12bbbf5c4135673f24 にあります。

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
    if (!item) {
        item = self.data;
    }
    id returnValue = @"";
    if ([item isKindOfClass:[NSArray class]]) {
        returnValue = @"value";//[item objectAtIndex:index];
    }

//    return @{@"index":@(index), @"value":returnValue}; // produces EXC_BAD_ACCESS in outlineView:objectValueForTableColumn:byItem:
    return returnValue;
}

このデータソースだけで本当に基本的なプロジェクトを作成しようとしましたが、まだ問題が発生しています。

4

2 に答える 2

1

でその場でアイテムを作成することはできませんoutlineView:child:ofItem:。すべてのアイテムはすでに存在している必要があります。少なくともアイテムが削除されるまで (つまり、ビューモデルの両方からユーザーに代わって削除されるまで)、またはアウトライン ビューに表示されているものがすべて閉じられる (ドキュメントが閉じられたなど) まで、アイテムはすべて存在し続ける必要があります。

辞書リテラル ( @{ … }) は、その時点での辞書の作成を表します。プログラムがその行に到達するたびに、同じアイテムの同じ子であっても、毎回新しい辞書を作成します。index(これは、との両方の値など、定数ではないものが辞書に含まれている場合に必ず当てはまりますreturnValue。)

ただし、辞書を保持していても、モデルに単純な古い辞書や配列を使用すると、非常に複雑なコードがすぐに作成されます。

ソリューション

2 つのプロパティを持つ NSObject の単純なサブクラスを作成します。

  • value(またはより具体的なもの)。これは、アウトライン ビューに表示している値の種類です。
  • children(またはより具体的なもの)、これは各アイテムに含まれる可能性のある子孫アイテムの配列です

次に、それらのオブジェクトの配列を保持します。の子を要求された場合nil、その配列内のオブジェクトの 1 つを返します。アイテムの子を要求された場合、そのアイテムはこれらのオブジェクトの 1 つになるため、その の 1 つを返しますchildren

アイテムのオブジェクト値 (唯一の列であると私が想定しているもの) を求められたら、アイテムの を返しますvalue。複数の列がある場合は、列ごとにプロパティを用意します。

最も重要なことは、アウトライン ビューが表示される前にこれらすべてのオブジェクトを作成し、 (項目の削除またはビューの却下によって) 操作が完了するまで保持しておくことです。必要に応じてアイテムを作成してから、アウトライン ビューがそれらに固執することを期待しないでください。それは、その仕事ではありません。それが管理者としてのあなたの仕事です。

項目はすべて同じクラスである必要はありません。アプリにとって意味がある場合は、Foos が Bars を所有し、Bars が Bazzes を所有するようにすることができます。ニーズが単純な場合は、すべてを Foo にする方が理にかなっています。意味のある方を実行してください。いずれにせよ、カスタム オブジェクトはコードを明確にします。

さらに言えば、リテラルによって作成された辞書をドロップするよりも、フロアにカスタム オブジェクトをドロップする場合の方がはるかに明白です。return [[Foo alloc] init…]「ああ、そうだ、それをしがみつく必要がある」ということを確認して思い出させるのがはるかに簡単です。

于 2013-10-07T02:14:44.937 に答える
0

一般に、初期化せずに返すことができる値を持つことはお勧めできません。

id returnValue; id returnValue = nil; である必要があります。具体的には、実際には NSArray (またはその子) ではない self.data にオブジェクトがある場合、オブジェクトへの未定義のポインターを返します。これは、ほぼ確実に不幸な結果をもたらします。

インデックスが実際にアイテムの境界内にあるという保証はありますか? これは不正なアクセス例外を生成するように見えますか?

于 2013-10-06T21:41:51.423 に答える