0

UITableView を使用して、小さな iOS プロジェクトに取り組んでいます。

テーブルを作成し、その中にいくつかのコンテンツを入れました:

-(void)configureCell:(UITableViewCell *)cell forIndexPath:(NSIndexPath *)indexPath {
    NSString *fileName = [testList objectAtIndex:[indexPath row]];
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *testPath = [docsDir stringByAppendingPathComponent:fileName];


    NSMutableDictionary *plistDict = [NSMutableDictionary dictionaryWithContentsOfFile:testPath];
    [[cell textLabel] setText:[plistDict valueForKey:@"title"]];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"indentifier"];
    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"identifier"];
        [cell autorelease];
    }

    [self configureCell:cell forIndexPath:indexPath];

    return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDir error:nil];
    testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];
    return [testList count];
}

これはうまくいきます。ダミーのコンテンツを含むテーブルがあります。しかし、このコードを追加するとき:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [testTable deselectRowAtIndexPath:indexPath animated:YES];
    NSLog(@"%d",[indexPath row]);
    NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);
}

テーブル内のセルを押すと、iOS シミュレーターがクラッシュします (終了しませんが、アプリは応答しなくなります)。この原因は次の行です。

 NSLog(@"%@",[testList objectAtIndex:[indexPath row]]);

この行を削除すると、完璧に機能します。このログ:

NSLog(@"%d",[indexPath row]);

通常どおり、行番号を返します。

奇妙なことは、configureCell 関数でまったく同じことを行うことです。

NSString *fileName = [testList objectAtIndex:[indexPath row]];

しかし、それはうまくいきます。

ここで何がうまくいかないのですか?

4

1 に答える 1

1

保持する必要がありますtestList。の次の行はそれを保持しtableView:numberOfRowsInSection:ません:

testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];

filteredArrayUsingPredicateあなたが所有していないオブジェクトを返します(オブジェクト所有権ポリシーに従って)。ivar にtestList直接アクセスしているため、retain メッセージを送信してオブジェクトの所有権を主張する必要があります (そして将来のある時点で解放します)。

testList = ...と は同じではないことに注意してくださいself.testList = ...。前者は ivar に直接アクセスしますが、後者はプロパティのアクセサーtestList(ある場合) を経由します。したがって、testList保持プロパティがある場合は、次のように簡単です。

self.testList = [dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]];

保持プロパティがない場合は、次のようにオブジェクトを保持できます。testList

testList = [[dirContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"self ENDSWITH '.stest'"]] retain];

プロパティはメモリ管理コードをカプセル化し、ボイラープレート コードを削減するため、プロパティを使用することをお勧めします。

于 2011-07-03T12:56:26.117 に答える