0

내 질문은 this question과 매우 비슷하지만 약간의 차이점이 있습니다.Obj-c : 범위 밖의 메서드 - 개체에서 NSArray를 반환합니다.

은 내가 NSString의 형태로하는 int XML에 걸리는 클래스가, 일부 개체를 구문 분석하고 어느 정도이 같은 NSArray에서 그들을 반환

다음
//Parser.m 
+(NSArray *)parseMessagesFromXml:(NSString *)xml 
{ 
    NSMutableArray *messages = [[NSMutableArray alloc] init]; 

    //do some work parsing the xml 
    //for each <row> 
    // Message *m = makeMessageFromRow(row); 

    return [messages autorelease]; 
} 

내보기 컨트롤러 클래스에 내가 선언있는 NSArray :

//MyViewController.h 
NSArray *messages; 
@property (nonatomic, retain) NSArray *messages; 

및 상기 방법을 사용하여 할당 :

//MyViewController.m 
messages = [Parser parseMessageFromXml:xml]; 
[[self tableView] reloadData]; 

그래서 여기에 문제가 있습니다 : 배열을 messages에 할당하면 배열에 요소가 있지만 모두 "범위를 벗어났습니다." 문제를 디버깅했습니다. 파싱 메서드가 올바르게 객체를 만들고이를 반환하기 전에 NSMutableArray에 추가한다는 것을 알고 있습니다. messages에있는 객체에 액세스하려고하면 내 응용 프로그램이 충돌하고 디버거에 EXC_BAD_ACCESS이 표시됩니다. 무엇보다 특이한 것은이있다 : 나는 법적으로 로컬 범위에서 볼 수있는 것처럼

NSArray *temp = [Parser parseMessageFromXml:xml]; 
//temp has all the right objects and they are in scope 

messages = temp; 
//messages has the objects, but cannot access them (they are out of scope). 

그것은이다,하지만 난 멤버에 할당 할 수 없습니다 내가 로컬 변수에 배열을 저장하는 경우는 잘 작동합니다 변하기 쉬운. 나는 반환 된 배열을 반복하면서 각 객체를 개별적으로 messages에 추가하려고 시도했지만 결과는 동일합니다. 범위를 벗어났습니다. 나는 이것에 관해 완전히 우둔하다.

messages은 이러한 개체를 보유 할 수없는 멤버 변수로 무엇입니까?

답변

2

문제는 배열이 출시된다는 것입니다. parseMessagesFromXml :에서 autorelease를 호출하면 앞으로 언젠가 릴리스되어야한다고 배열에 알립니다. 이것은 테이블이 데이터를 다시로드하기 전에 발생합니다. 배열이 해제되지 않도록 배열을 다시 유지해야합니다. 이 경우 인스턴스 변수를 직접 설정하는 대신 접근 자 메서드를 사용하여 속성을 설정하는 것처럼 간단합니다.

//MyViewController.m 
self.messages = [Parser parseMessageFromXml:xml]; 
[[self tableView] reloadData]; 
+0

개념적으로보기 컨트롤러는'parseMessageFromXml' 결과의 "소유권을 가져야합니다". – vicvicvic

+0

정확히 내가하고있는 일입니다. 또한 메시지는 retain 속성을 사용하므로 할당이 해제되지 않습니다. 그리고 그 위에, 나는 신중하게 문제를 디버깅했고, 나는 그것이 조기에 할당 해제되지 않는다는 것을 안다. 그가 4 번째 코드 예제를 보았습니다. 임시 NSArray에서 객체는 여전히 범위 내에 있지만 메시지와 동시에 범위를 벗어납니다. 같은 대상, 같은 시간, 그러나 하나는 볼 수 있고 다른 하나는 그렇지 않습니다. – mtmurdock

+0

@mtmurdock ughoavgfhw ('self.messages = [Parser parseMessageFromXml : xml];)의 제안대로 프로퍼티를 사용하는 대신 배열을 인스턴스 변수 ('messages = [Parser parseMessageFromXml : xml];) . –