0

次のように定義された ViewController があります。

@interface SectionController : UITableViewController {
   NSMutableArray *sections;
}
- (void) LoadSections;

LoadSection が呼び出されると、NSURLConnection が呼び出されて URL がロードされ、次にそれが呼び出されます。

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    [connection release];
    [responseData release];

    NSDictionary *results = [responseString JSONValue];
    NSMutableArray *jSections = [results objectForKey:@"Items"];
    sections = [NSMutableArray array];

    for (NSArray* jSection in jSections)
    {
        Section* section = [Section alloc];
        section.Id = [jSection objectForKey:@"Id"];
        section.Description = [jSection objectForKey:@"Description"];
        section.Image = [jSection objectForKey:@"Image"];
        section.Parent = [jSection objectForKey:@"Parent"];
        section.ProductCount = [jSection objectForKey:@"ProductCount"];
        [sections addObject:section];
        [section release];
    }

    [jSections release];
    [results release];

    [delegate sectionsLoaded];

    [self.view reloadData];
}

データは正しく解析され、多くの項目で満たされたセクションができました。

[self.view reloadData] を呼び出すと、セルにデータを表示するデリゲート メソッド cellForRowAtIndexPath へのコールバックが強制されますが、この時点でセクションは再び nil になります。

誰かが私の間違いを指摘できますか?私は客観的なcの初心者であり、おそらくポインターの問題であることを認めなければなりません。必要なことは、reloadData を呼び出した後にセクションの値を保持することです。

どうもありがとう。

4

2 に答える 2

1

新しいコードを見ると、問題は明らかです。

sections = [NSMutableArray array];

なるべき

[sections release];
sections = [[NSMutableArray alloc] init];

配列が再び「nil」になることはなく、代わりに割り当てが解除され、無効な参照が取得されることに注意してください。これにより、逆参照時にクラッシュが発生する可能性があります。

Objective-C を初めて使用する場合、参照カウント メモリ管理に関するいくつかの記事を読むことをお勧めします。これは、Objective-C を初めて使用する場合は明らかではなく、しばしば間違いにつながる可能性があるためです (つまり、autorelease はまったく魔法ではありません)。

于 2010-10-09T16:46:13.553 に答える
0

ここですべてのメモリリークを回避する最善の方法は@property (nonatomic, retain) NSMutableArray *sections;、すべての男性管理作業がシステムによって正しく管理されることを確認できるプロパティを使用することです。setSections: を実行するときにプロパティが値を保持することを忘れないでください。そのため、ここで autoreleased オブジェクトを渡す必要があります。

self.sections = [NSMutableArray array];

...

[self.sections addObject:section];

また、すべての問題を回避するために、このメソッドにのみ存在する必要があるすべてのオブジェクトを autorelease にするようにしてください。このような:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];

NSDictionary *results = [responseString JSONValue];
NSMutableArray *jSections = [results objectForKey:@"Items"];
self.sections = [NSMutableArray array];

for (NSArray* jSection in jSections) {
    Section* section = [[[Section alloc] init] autorelease];
    section.Id = [jSection objectForKey:@"Id"];
    section.Description = [jSection objectForKey:@"Description"];
    section.Image = [jSection objectForKey:@"Image"];
    section.Parent = [jSection objectForKey:@"Parent"];
    section.ProductCount = [jSection objectForKey:@"ProductCount"];
    [self.sections addObject:section];
}

[delegate sectionsLoaded];

[self.view reloadData];

}

また、解放しようとしているオブジェクトのほとんどは既に自動解放されています。メソッドに渡されたすべてのパラメーターは手動で解放しないでください。JSONValue も自動解放されたオブジェクトと、列挙または objectForKey の呼び出しによって取得したものを返す必要があると思います。

于 2012-12-17T19:40:53.710 に答える