0

私は iOS 開発の初心者で、ここや Google で解決策を見つけることができなかったので、必死になって質問しています。

UIViewController のサブクラスであるクラス「ViewController」があります。ここには、次のものがあります。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([self.bookTitle.text length] > 0)
        self.entries = [self.bookLibrary searchForBook:self.bookTitle.text];

    if ([segue.identifier isEqualToString: @"BookList"]) {
        TableViewController *controller = (TableViewController *)segue.destinationViewController;
        controller.itemCounter = [self.entries count];
        controller.bookLibrary = [self.entries allValues];
    }
}

ストーリーボード上のこのビューには、グリッドにドラッグ アンド ドロップした Table View Controller への接続があります。下部にある [Table View Controller] をクリックし、カスタム クラスの入力ボックスにカスタム クラスの [TableViewController] を設定しました。

さて、私が理解していることから、上記の方法はすべてのデータを適切に TableViewController に渡しています。

これは、TableViewController にあるメソッドの 1 つです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *simpleTableIdentifier = @"BookCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
    }

    Book* book =  [self.bookLibrary objectAtIndex:indexPath.row];

    cell.textLabel.text = book.title;
    NSLog(@"%@", book.title);
    return cell;

}

NSLog エントリはすべての本のタイトルをコンソールに出力しているので、データが渡されていることがわかります。しかし、プログラムを実行し、ボタンをクリックしてテーブル ビューを表示すると、それは単なる空のテーブルです。ヒントはありますか?プロジェクト全体をアップロードできます。これに数時間いて、少しイライラしました。助けてください :(

編集:応答は、テーブル メソッドでデータ変数の状態を確認することを提案しました。それらの状態は私が思っているものではなく、NSLog を使用して値を出力する必要があることを示唆しています。まさにそれを行い、すべての値が出力されているのを見ることができます。わかりません...実際、値が割り当てられています。問題は、データが欠落していることではありません。

4

1 に答える 1

0

VC として UITableViewController サブクラスを使用していること (パレットから UITableViewController ui オブジェクトを使用している場合)、または UITableView のデリゲートとデータソース プロパティを VC に適切に接続していることを確認してください (パレットから UITableViewController ui オブジェクトを使用している場合)。プレーンな UIViewController オブジェクトとサブクラスを使用)。

(質問に関するコメントを参照)。

これを試して:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSLog(@"bookLibrary.count %d", bookLibrary.count);
    return [bookLibrary count];
}

物事はあなたが思っているものではないことがわかります... の実装を追加し、それviewDidLoadviewWillAppear加えて、それぞれ独自の「私はここにいます」NSLog ステートメントを追加し、2 番目のビュー コントローラーが表示されるフローをトレースします。繰り返しますが、フローが想定どおりに機能していないシーケンスの問題がいくつかあることがわかります。


追加されたコメント:

最終的に、問題の原因は、「送信」コントローラーのセグエメソッドの準備の次の行です。

controller.bookLibrary = [self.entries allValues];

これは何をしているのですか?allValuesDictionary オブジェクトを呼び出しています。そのメソッドは、値を含む新しい配列 (!) を生成します。その新しい Array オブジェクトを永続的なストレージに保存しません。それを使用して設定するだけです:

controller.bookLibrary = ...

したがって、そのステートメントが実行された直後には、次のようになります。

  • 次の 1 つの変数/ホルダーにのみ格納した prepareForSegue メソッド (コードが実行されている場所) の Array オブジェクト:
  • 宛先ビュー コントローラー (TableViewController) 内のそのオブジェクトへの弱いポインター

メソッドは終了します。

によって返される配列は[... allValues]、ソース ビュー コントローラー内のどこにも保持されていないため、ガベージ コレクションからそれを保持する唯一のものは、宛先ビュー コントローラー内の配列へのポインターです。

しかし、そのポインターは弱いポインターです。定義により、それがオブジェクトへの唯一のポインターである場合、ポインターは nil に設定され、オブジェクトはガベージ コレクションのために解放されます。ふふっ! 配列オブジェクトはなくなり、nil ポインターを保持したままになります。

あなたが発見したように、「レシーバー」を強力に設定すると、他のコードが終了し、それが配列への唯一のポインターになった後でも、その配列オブジェクトを保持できます。

(そして、あなたのコードは 2 回呼び出されていません。ロギングをよく見ると、またはテーブルの get-row-count メソッド内にブレークポイントを設定すると、1 回だけ呼び出されていることがわかります。 「I have 8 objects」のロギングは、TableViewController ではなく、他のコードで行われています。)

于 2013-03-10T21:01:13.077 に答える