2
- (void)viewDidLoad
{
    [super viewDidLoad];
    [VenueManager searchNear:@"Orlando"
                      onLoad:^(NSArray *objects) {
                          self.locationObjects = objects;
                          [self.tableView reloadData];
                   } onError:^(NSError *error) {
                      NSLog(@"%@", error);
    }];

}

このコードは、UITableViewController クラスの viewDidLoad メソッドにあります。これは、RestKit を使用して FourSquare から JSON ファイルを解析するための出発点です。[self.tableView reloadData]; を配置するまで、テーブル ビューにオブジェクトを表示できなかったため、髪を引っ張っていました。- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)その呼び出しがなければ、ブロックが実行された後に locationObjects が nil になるため、アプリは私にさえヒットしませんでした。

私がそれをデバッグする前に、私がブロックにいたときに self.locationsObjects = objects が機能しました(ちなみに私はブロックに非常に慣れていません)。ブロックから出るとすぐに、デバッガーは、割り当てステートメントにブレークポイントがあったときのオブジェクトと同じように、30 個のオブジェクトがあると言っていましたが、locationObjects は nil であると言うでしょう。

ここで何が起こっているのかを理解するのを手伝ってくれる人がいますか。

追加情報:

現在、すべてが機能しているか、機能しているように見えます。私のテーブルには、JSON ドキュメントからのオブジェクト リクエストが取り込まれています。もともと、私は通常の ViewController でこれとまったく同じことを行っていてobjects、ブロックから を に等しく設定しようとしていましたlocationObjects。次に、メソッドを使用して、多数のチュートリアルから学んだ標準メソッドで tableViewController にprepareForSegue渡そうとしました。locationObjectsSIGBAT エラーが発生します。認識できないセレクターがテーブル ビュー コントローラーに送信されたため、スレッドが終了していました。locationObjectsデバッグを通じて、prepareForSegue メソッドで nil になる可能性があることがわかります。以下は、viewController ファイルのコードです。

locationTableViewController.locationObjects = self.locationObjects;また、タイプ NSArray のポインターを強力な NSArray に割り当てること、またはそのようなことについて警告が表示されます(その後、コードを機能させるために多くの変更を加え、いくつかのストーリーボード アセットを削除したため、100% ではありません)言葉遣いは確かです)。

@implementation CoffeeShopViewController

@synthesize venueCountLable = _venueCountLable;
@synthesize locationObjects = _locationObjects;

- (void)viewDidLoad
{
    [super viewDidLoad];
    [VenueManager searchNear:@"Orlando"
                      onLoad:^(NSArray *objects) {
                          self.venueCountLable.text = [NSString stringWithFormat:@"%d", objects.count];
                         self.locationObjects = objects;
    } onError:^(NSError *error) {
        NSLog(@"%@", error);
    }];

}

- (void)viewDidUnload
{
    [self setVenueCountLable:nil];
    [super viewDidUnload];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"locationTableSegue"])
    {
        LocationTableViewController *locationTableViewController = segue.destinationViewController;
        locationTableViewController.locationObjects = self.locationObjects;
    }
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

@end
4

1 に答える 1

1

試す:

 @property (nonatomic, copy) NSArray *locationObjects;' 

これが機能する理由を編集します。

正直なところ、これが機能し、強い機能が機能しない根本的な理由は本当にわかりません。私がこの問題を見たとき、strong は保持と同等であるように思えました。strong の代わりに copy を挿入すると、locationObjects が無効にならないようにすることができます。もう一度考えてみると、自分の仮定が間違っている可能性があるのではないかと思いました。保持とは、文字通り「このオブジェクトを保持している人物がもう 1 人いるため、このオブジェクトを解放しないでください」という意味です。

ただし、その動作は多少異なります。これを参照してください。

以下の Malaxeur の回答とコメントが示すことは、あなたの例の NSArray に当てはまる可能性があります。範囲外 (ブロック終了) になると、使用できなくなり、ARC が主張します。次に copy を使用すると、locationObjects のためだけにメモリ内に別のスペースが作成されます。このスペースは、解放するまで永久に残ります。

ブロックを完全に理解したことがないので、これが完璧な説明だとはまだ考えていません。私はこれをよりよく知っているすべての人に公開しておき、有用なものを入手するとすぐにいっぱいになります.

于 2012-11-05T03:02:25.487 に答える