2011-03-30 5 views
1

로 전송 메시지 이것은 내 첫 번째 게시물입니다 stackoverflow.com 때문에 (되감기) 종류하시기 바랍니다)목표 - C/아이폰 OS : 할당이 해제 된 경우

나는 누구의 목적 (블로그 게시물을 표시하는 것입니다 탐색 기반 응용 프로그램을 제목)을 JSON을 사용하여 테이블보기에 표시합니다. 셀이 화면에서 빠져 나왔을 때 문제가 발생했습니다. EXC_BAD_ACCESS를 얻었습니다 (할당 취소 된 인스턴스에 메시지를 보냈기 때문에). 그래서 어디에서 왔는지 이해하려고 애를 썼습니다. 해결책을 찾았습니다. 그러나 사실은 문제가 어떻게 발생하는지 정확히 이해하지 못합니다. 그래서 나는 누군가에게 나를 계몽 할 필요가있다. 나는 이것이 근본적인 이해라고 생각한다!

JSON 웹 서비스에 대한 연결이 완료되면 JSON 코드를 구문 분석하여 블로그 게시물 (recentPosts) 목록을 가져온 다음 각 게시물 (blogArticle)에 대한 BlogArticle 개체를 만들고 MutableArray에 저장합니다 바르 (allEntries)와 테이블 뷰의 행 삽입 :

- (id)initWithDictionary:(NSDictionary *)article 
{ 
    if (self = [super init]) 
    { 
     // title = [[[article valueForKey:@"title"] gtm_stringByUnescapingFromHTML] copy]; 
     // title = [[NSString alloc] initWithString:[[article valueForKey:@"title"] gtm_stringByUnescapingFromHTML]]; 
     title = [[article valueForKey:@"title"] gtm_stringByUnescapingFromHTML]; 
    } 

    return self; 
} 

그래서 모든 목표 - C 프로그래머 : 여기

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{ 
    [connection release]; 

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    [responseData release]; 

    NSError *error; 
    SBJsonParser *json = [[SBJsonParser new] autorelease]; 
    NSDictionary *recentPostsData = [json objectWithString:responseString error:&error]; 
    [responseString release]; 


    NSArray *recentPosts = [recentPostsData objectForKey:@"posts"]; 

    int i = 0; 
    for (NSDictionary *post in recentPosts) { 
     BlogArticle *blogArticle = [[BlogArticle alloc] initWithDictionary:post]; 
     [allEntries insertObject:blogArticle atIndex:i]; 
     [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:i inSection:0]] withRowAnimation:UITableViewRowAnimationRight]; 
     i++; 
    } 
} 

문제의 기원으로 켜진 BlogArticle 객체의 초기화이다 누가 나를 싫어하는 사람이 아니야. 그 제목은 할당되기 전에 할당되지 않는다는 것을 말하십시오. 위의 두 줄 중 하나의 주석을 제거하면 작동합니다.

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

    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    } 

    NSLog(@"indexPath.row = %i", indexPath.row); 

    // Configure the cell. 
    BlogArticle *article = [allEntries objectAtIndex:indexPath.row]; 

    cell.textLabel.text = article.title; 

    return cell; 
} 

을 지금, 나는 그것이 바르를 할당 어디없이/일을 컴파일 않는 이유를 이해하기 위해 필요한 정확하게 문제를 (원인 : 여기, 그 제목 변수로 셀을 초기화 할 때이 프로그램은 정확히 충돌 또는 정확하게 제목의 내용이 공개되어 프로그램이 중단되는 경우). iOS 환경에서 메모리 관리에 대한 좋은 자료 (멍청한 답변)가 있으면 감사하겠습니다. 사전 :

+1

관련없는 도움이 될 희망 발표 될 예정이다 , 당신은 'for'주기에'blogArticle' 인스턴스를 누설하는 것처럼 보입니다. –

+0

메모리 관리에 관해서는, Apple의 [docs] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html#//apple_ref/doc/uid/20000043- BEHDEDDB) 당신이 알아야 할 모든 것이 있어야합니다. "메모리 관리 규칙"섹션을 정말로 이해하십시오. –

+0

"누출"이란 무엇을 의미합니까? 메모리를 할당하고 결코 할당을 해제하지 않습니까? – teum

답변

3

이 줄

title = [[article valueForKey:@"title"] gtm_stringByUnescapingFromHTML]; 

에서

감사는 문자열을 오토 릴리즈 할당된다. 본질적으로, autoreleased 문자열이 메서드의 마지막에 릴리스 될 것이라고 생각하십시오 (오래 지속될 수 있지만 그렇게 생각하는 것이 유용합니다).

당신은 방법 gtm_stringByUnescapingFromHTML의 이름 alloc, new, copy 또는 mutableCopy로 시작하지 않기 때문에 문자열이 오토 릴리즈 알고. 당신이 그렇게 말까지

title = [[[article valueForKey:@"title"] gtm_stringByUnescapingFromHTML] retain]; 

지금 당신이 문자열을 소유하고는 공개되지 않습니다 : 당신은이에 retain을 추가 할 수 있습니다

그것이 오토 릴리즈 점점 중지합니다.

제가 알고있는 가장 좋은 요약은 Apple의 설명서 here입니다.

+0

좋아, 사실은 내가 autoreleased 개체를 반환하는 방법을 인식하는 방법을 궁금 해서요, 팁 주셔서 감사합니다! – teum

1

글쎄, 문제는 자신의 메모리를 직접 관리하려는 경우 개체를 초기화해야한다는 것입니다. 왜 지금 당신은 제목의 기억을 관리해야합니까?

아주 간단 : 모든 객체 참조는 Array, Set, Dictionary 등에 저장됩니다.배열, 사전 및 집합에 의해 관리됩니다.

셀에이 참조를 사용하면 ("제목 = ..."으로 작성) 참조를 셀에도 추가합니다. 그리고 이제 셀은 객체 참조를 담당합니다. 따라서 tableView가 메모리를 절약하기 위해 수시로 발생하는 셀을 해제하려는 경우 셀이 제목 객체를 해제합니다. 그리고 이것은 NSDitionary가 아주 슬프게 만들 것입니다. 왜냐하면 NSDictionary는 자체 내에 저장된 객체를 돌보고 싶어하기 때문입니다.

그래서 당신은있는 tableView-방법 다음 작성할 수

cell.textLabel.text = [article.title retain]; 

또는 자신 만의 방법을 주석 처리 된 줄을. 즉, 개체의 저장소 수준을 올리면 저장 수준이 1 씩 감소합니다. 스토리지 레벨이 제로에 도달 할 경우, 완전히 (즉, 당신의 테이블 셀이 해제되는 경우, 발생하고있는 NSDictionary한다)

나는 당신에게 조금 :) 문제에

+0

자세한 설명을 읽어 주셔서 감사합니다. – teum

관련 문제