0

(iPhone Objective-C でのプログラミング)

クラス レベルの NSString* を作成し、プロパティ (nonatomic,retain) を追加してコードを合成します。 stringByAppendingString 関数を使用して文字列を際限なく変更し、NSLog を使用して文字列を表示できます。これはすべて、サブクラスのオーバーライドされた viewDidLoad 関数で行われます。tableView のセルに何を表示するかを決定するときに cellForRowAtIndexPath 関数から同じ変数にアクセスしようとすると、プログラムがクラッシュします。誰にも手がかりはありますか?

関連コード:

@interface InfoViewController : UITableViewController {
    NSString *shipAddr;
}
@property (nonatomic,retain) NSString *shipAddr;

@synthesize shipAddr;

VIEWDIDLOAD:

shipAddr = [[[NSString alloc] initWithString:@""] retain];

**ここでクラッシュ:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(shipAddr);

**

4

4 に答える 4

2

実際には元の文字列を二重に保持しているため、リークが発生しますが、それがクラッシュの原因ではありません。

stringByAppendingString:自動解放された文字列を返すため、クラッシュしています。したがって、オリジナルを何回保持してもかまいません。stringByAppendingString:(または他のメソッドのいずれかを)呼び出すたびstringByWhateverに、有効期間が制限された新しい文字列を取得します。

あなたのコードでは、常に に代入しself.shipAddr@""最初は文字列に代入することをお勧めします。このself.shipAddrバージョンは、メモリ管理を自動的に処理します。

于 2009-07-14T00:28:10.613 に答える
0

@synthesizeステートメントがヘッダーではなく実装ファイルにあることに気付いていると思います。

またviewDidLoad、そうしなければならない場合は、次のようにすればよいと思います。

self.shipAddr = @"";

プロパティはすでに渡された引数を保持するように定義されているためです。

最後に気付いたのは、NSLog への呼び出しは次のようにする必要があるということです。

NSLog(@"%@", shipAddr);

関数の形式は次のようになります。void NSLog(NSString *format, ...);

はい、ブレントが述べたようにstringByAppendingFormat、自動解放された文字列を返すため、他のメソッドでそれを見る前におそらく「消える」でしょう。したがって、これを使用する必要があります:

self.shipAddr = [shipAddr stringByAppendingFormat: blah blah];

これは、定義したように、渡された引数を保持し、問題を処理する shipAddr のプロパティを使用するためです。

于 2009-07-14T00:28:26.183 に答える
0

tableView:cellForRowAtIndexPath: の前に viewDidLoad が呼び出されますか? その関数内で参照すると、文字列が初期化されていないか解放されているように聞こえます。viewDidLoad で文字列を割り当てて保持していることを考えると (実際にはそこに保持する必要はありません)、まだ初期化されていないと思います!

于 2009-07-14T00:28:37.057 に答える
0

viewDidLoad および tableView:cellForRowAtIndexPath: メソッドの先頭に NSLog ステートメントを配置してみてください。後者が最初に実行されている場合、変数が作成される前に変数にアクセスしようとします。

shipAddr が十分に早い段階であることがわかっている場合は、初期化を init メソッドに入れます。

于 2009-07-14T00:25:25.417 に答える