2012-05-10 7 views
0

내가 지금 데 것은누출 메모리 문제, 메모리 관리

@interface ClassA: NSObject <DelegateA> 
-(id)initWithData:(NSData*)data; 
+(Stores*)makeClass:(Class) name fromData:(NSData*)data; 
@property (assign) NSMutableArray *arr; 
@property (assign) RXMLElement  *rxmlRoot; 
@end 

classA.m

-(id)initWithData:(NSData*)data { 
     self = [super init]; 
     if (self) { 
      arr  = [[NSMutableArray array] retain]; 
      rxmlRoot = [[RXMLElement elementFromXMLData:data] retain]; 

     } 

     [rxmlRoot iterate:node with:^(RXMLElement *e){ <--------get warning at here 
      NSLog(@"element is %@",e.tag); 
      Detail *detail = [[[Detail alloc] init] autorelease]; 
      [detail setLat:  [e attribute:@"lat"]]; 
      [detail setLon:  [e attribute:@"lon"]]; 

      [arr addObject:detail]; 

     }]; 
     return self; 
     } 

     +(classA*)makeClass:(Class) name fromData:(NSData*)data{ 
      ClassA *classA = [[ClassA alloc] initWithData:data]; 
      return [storeClass autorelease] ; 

     } 

및 RaptureXML.m

classA.h

입니다

+ (id)elementFromXMLData:(NSData *)data { return [[[RXMLElement alloc] initFromXMLData:data] autorelease]; } - (id)initFromXMLData:(NSData *)data { if ((self = [super init])) { xml_ = [[TBXML alloc] initWithXMLData:data]; tbxmlElement_ = xml_.rootXMLElement; } return self; } 

경고 :

질문 역 참조 널 포인터 결과 ('자기'를 통해) 인스턴스 변수 접근 :이 경고를 얻는 방법이 문제를 해결하는있는 이유. 제발 조언 해주세요. 에서 [rxmlrRoot itertate ... 등 이동이다

if (self) { 

} 

의 모든 초기화 코드를 넣어 감사

+0

가를 ClassA = *를 ClassA의 첫 번째 및 세 번째를 ClassA이다 [를 ClassA ALLOC] initWithData : 데이터]; 오타이기 때문에 소문자입니까? – fsaint

+0

감사합니다. 방금 편집했습니다 – tranvutuan

답변

1

보십시오. 그 if 문으로

일반적으로 모든 초기화 구문 (init 메소드의 모든 것)은 if (self) 블록에 있어야합니다. 그 이유는 슈퍼 클래스가 nil을 리턴했을 때 블록이 실행될 코드 밖에있다. (else if if (! self) {...). super 메소드 (초기화 메소드가 O-C의 일반 메소드 일 경우)가 호출되지 않으면 코드를 계속 실행하지 않으려합니다.

나는 또한 항상 자신의 커스텀 클래스 (이것은 슈퍼 init를 호출하는 것이다)에 지정된 이니셜 라이저를 갖도록 가르쳐졌고, 클래스 내의 다른 모든 초기화 기들이이 지정된 이니셜 라이저를 호출한다. 전의.

이렇게하면 해당 한 지점에서 모든 트래픽을 제어 할 수 있습니다.

+0

감사합니다. 경고가 사라졌지만 경고에 대한 설명도 필요합니다. – tranvutuan

+2

당신은 그 자체가 nil 일 수 있다고 말하고 있습니다. 그래서 컴파일러는 말합니다 - 자기가 0 인 경우 'arr'과 같은 다른 무언가를 사용하는 코드로 갈 때 충돌이 발생합니다. 당신은 물론 자기가 결코 무용하지 않을 것이라는 것을 '안다'는 것이다. (만약 메모리가 부족하다면 어쨌든 분명히 충돌 할 것이다!) - 그러나 컴파일러는 그것을 모른다. –

+0

@ttran Tom이 말한 바로는 맞습니다. 답변에 대한 설명을 추가했습니다. 유사한 문제 : http://stackoverflow.com/questions/10246945/instance-variable-access-via-self-results-in-a-null-pointer-dereference – Patrick

0

[rxmlRoot iterate:node with:^(RXMLElement *e){ ... }] 전화에서 노드 란 무엇입니까? 로컬 변수 나 iVar가 아닙니다. 그것은 글로벌인가 아니면 다른 곳에 존재 하는가?

언제 까지나 이것이 초기화되었는지 확인하십시오.

0

블록 내에서 인스턴스 변수 arr이 참조로 액세스됩니다. 미묘한 메모리 관리 규칙으로 인해 액세스로 인해 self이 블록에 보관됩니다.

self이 nil 일 수있는 컴파일러에 대한 단서이므로 블록에 의한 self의 암시적인 보유로 인해 널 포인터 참조가 발생할 수 있습니다.

고치 닐 조기 종료를 확인하기 위해 :

if (!(self = [super init])) { 
    return nil; 
} 

// now it is impossible for self to be nil and cause a null pointer dereference 
// when self is implicitly retained by the block 

// ...continue initialization