문제

다음과 같은 방법이 있습니다.

-(void)testAPIModule {
    self.requests = [NSMutableArray array];
    NSLog(@"making arrays");
    /*(A)*/ id array1 = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithFloat:2], nil];
    /*(B)*/ id array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:4], [NSNumber numberWithInt:5]];
    NSLog(@"made array=%@",array2);

    for( ServerRequest *req in self.requests ) {
        [Networker sendRequest:req withDelegate:self];
        [req release];
    }
}

코드가 예상대로 실행됩니다.

그러나 라인 (A)를 주석 처리하거나 라인 끝의 ",nil"을 제거하면 EXC_BAD_ACCESS (B)행에 오류가 있습니다!디버거에 따르면 +[NSArray arrayWithObjects] 내장 생성자의 CFRetain에서 오류가 발생합니다.

또한 (A) 행을 주석 처리하고 for(...) 루프를 주석 처리하면 코드가 메서드를 통해 실행됩니다.

이것은 나에게 매우 예상치 못한 일입니다.(B)라인에서 내가 뭘 잘못하고 있는 걸까?그리고 (A)행에서 완전히 다른 배열을 생성하면 메서드가 실행되는 이유는 무엇입니까?그리고 왜 for(...) 루프를 주석 처리하면 그 앞에 있는 라인 (B)의 오류가 방지됩니까?

누군가 이것이 왜 설명할 수 있습니까?아니면 적어도 디버깅에 대한 조언을 주실 수 있나요?메소드가 한 번만 실행되고 "self"가 유효한지 이미 확인했습니다.

도움이 되었습니까?

해결책

편의방식을 사용하는 경우 arrayWithObjects, 마지막 요소로 nil을 지정해야 합니다.

문서에 따르면 다음과 같습니다.

arrayWithObjects:

인수 목록의 개체를 포함하는 배열을 만들고 반환합니다.

+ (id)arrayWithObjects: (id)firstObj, ... 

매개변수

첫 번째Obj, ...
nil로 끝나는 객체의 쉼표로 구분된 목록입니다.

다른 팁

기타 경고 플래그에 -Wformat을 추가하면 컴파일러가 누락된 nil을 자동으로 찾아냅니다.

두 번째는 요소가 스택에서 모두 동일한 위치에 있기 때문에 첫 번째 이후에 작동합니다.따라서 첫 번째 항목에서 반환된 후에도 스택에는 여전히 다음 항목에 대한 포인터가 포함되어 있습니다. [NSNumber numberWithInt:1], 포인터 [NSNumber numberWithFloat:2] 및 nil(그리고 자동 릴리스 풀이 아직 배수되지 않았기 때문에 해당 포인터는 여전히 유효합니다!)nil 없이 두 번째 호출을 호출하면 스택의 포인터가 대체되지만 nil은 변경되지 않은 채로 남습니다.두 번째 시도에 세 개의 숫자가 있었다면 세 번째 숫자가 nil을 덮어쓰고 다음 숫자가 남게 되므로 같은 방식으로 충돌했을 가능성이 높습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top