Objective-C Cocoa를 사용하여 반자동 참조 카운팅 메모리 관리 작업을하고 있습니다. 객체에 메모리를 할당하거나 객체를 보유하거나 객체에 copy
메소드를 호출하면 보유 수 (참조 횟수)가 1 씩 증가합니다. 객체에 release
을 호출하면 보유 수를 1 씩 감소시킵니다. 객체에 autorelease
을 호출하면 앞으로 어떤 시점에서 객체에 대해 release
이 호출됩니다 (기본 실행 루프 중에는 자신의 코드가 실행되지 않을 때 참조로 인해 참조가 풀링되지 않습니다. 그것을 사용하려고 시도하고있다). 보유 수가 0에 도달하면 오브젝트를 할당 해제 할 수 있습니다. 당신이 객체에 retain
를 호출하는 경우 일반적으로
는, 당신은에 관심을 신호하고, 당신은 객체에 더 이상 관심이 없을 때 당신은 어떤 점에서
release
또는
autorelease
통화를 할 책임이 있습니다 . 마찬가지로 개체에
alloc
또는
copy
메서드를 호출하면 해당 개체에 대한 관심이 표명되고 그 선의 아래 어딘가에 또는
autorelease
과 일치해야합니다.
는
이 링크를 꽤 많이 지침 애플의 용도를 커버 (당신은 사용해야합니다) 메모리 관리 :
ClassOne *pointer = [[ClassOne alloc]init];
pointer
포인트 : Simple rules for memory management in Cocoa
가의 라인에 의해 코드 라인을 통해 가자 새로 할당 된 ClassOne 객체에 retain count가 1인데, alloc을 호출 한 이후입니다. 앞으로 release
또는 autorelease
번으로 pointer
으로 전화해야 할 의무가 있습니다. 우리가에 ALLOC라고 이후 1의 유지 카운트
새로 할당 ClassTwo 객체에
ClassTwo *foo = [[ClassTwo alloc]init], *foo2;
foo
점. 앞으로 release
또는 autorelease
으로 전화하여 foo
에 연락해야 할 의무가 있습니다.
foo2
은 특히 현재 아무 것도 가리 키지 않습니다. 사용하는 것은 안전하지 않습니다.
pointer
foo2 = [foo add: pointer];
은 (그것이 의미하는 무엇이든 우리가 구현을 모르는)
foo
에 추가되었습니다.
foo
은
pointer
에
retain
을 호출하여 해당 관심을 알리고 필드로 추가하거나 컬렉션에
pointer
을 추가했을 수 있습니다.이 경우 개체가 추가 될 때
retain
을 호출하는 것은 컬렉션의 책임입니다. 객체가 제거 될 때
release
). 어쨌든 코드 블록에는 영향을 미치지 않으므로 코드 블럭에 아무런 영향을 미치지 않습니다.
이 메서드에서 반환하는 참조는 pointer
일 수도 있고 pointer
의 자동 변환 된 복사본 일 수도 있습니다. 우리는 API 또는 구현에 액세스 할 필요가 없으므로이를 알려줍니다.
두 경우 모두 release
에게 전화하는 것은 당사의 책임이 아닙니다. 메소드에 이름에 copy
이 있거나 반환 된 참조 (예 : foo2 = [[foo add:pointer] retain];
)에 retain
을 호출 한 경우 보유 수는 1 씩 증가했으며 release
또는 autorelease
을 호출하는 것은 Google의 책임이었습니다. foo
참조하는 오브젝트가 공개되어
[foo release];
은 그것의 카운트가 예를 들면 1만큼 감소 된 유지 즉, 우리는 라인 (2)에서 만든
alloc
호출이 쌍 때문에 카운트를 유지 0으로 떨어 지므로
foo
이 해제 될 수 있습니다.
일반적으로 개체가 할당 취소되었는지 여부는 신경 쓰지 않습니다. alloc
, copy
또는 retain
번의 전화 번호가 release
또는 autorelease
과 같은 번호와 일치하는지 확인해야합니다. 우리가 언제든지 객체에 관심을 등록하면 우리의 관심을 해제하는 것이 우리의 책임입니다. 그렇지 않으면 메모리 누수가 발생합니다.
foo
foo = foo2;
지금
foo2
에 의해 참조 동일한 개체를 가리 킵니다. 우리가
foo2
을 얻었을 때
alloc
또는
copy
메소드를 호출하지 않았으며
retain
을 호출하여 관심을 등록하지 않았 음을 기억하십시오.
release
에
foo2
으로 전화 할 의무가 없으므로
release
에
foo
으로 전화 할 의무가 없습니다.
[pointer release];
pointer
'는의 1.이에 의해 감소 된 수를 유지
0으로 그것의 유지 수를 가져왔다 수 있습니다 여부, 우리가 그것을 추가 할 때 그것으로 무엇을했는지
foo
에 따라 달라집니다. 여전히 우리는 상관하지 않습니다. 우리는 처음에 만든
alloc
전화와 일치하도록
release
을 호출하여
pointer
에 대한 책임을 완료했습니다. 이 호출 후에도
pointer
이 여전히있을지라도, 우리는 그 가정을 할 수 없으며, 이전에 포인터에 의해 참조 된 객체로 무엇을하려해도 실수가 될 수 있습니다. (
pointer
을 자유롭게 변경할 수는 있지만).이 코드의 저자는 애플의 메모리 관리 규칙을 다음 한 경우
[foo release];
은, 다음이 필요하지 않습니다. 우리는 release
을 foo
또는 foo2
에 전화 할 책임이 없습니다 (그들은 같은 물체를 가리 킵니다. 기억하십시오). 이렇게하면 코드가 손상되지 않습니다. nil
참조 서에있는 어떤 것도 호출하는 것은 본질적으로 아무 작업도하지 않습니다. 그러나 코드를 검토하는 사람은 혼란을 야기 할 수 있습니다.
이제이 코드의 작성자가 메모리 관리 규칙을 위반했을 수 있습니다. 그는 add
호출을 autorelease
으로 호출하지 않고 pointer
사본을 반환 할 수 있습니다.이 경우 호출자는 release
을 호출해야합니다. 이것은 매우 나쁜 형식이며, 메모리 관리 규칙을 위반하는 코드를 실행해야하는 경우 사용하는 위치와 향후 혼란을 피하기 위해 규칙을 위반하는 방법을 문서화하십시오.
해당 클래스의 클래스 이름은 무엇입니까? –
덧붙여 말하자면, 코드를 익명으로 처리하는 과정에서 이러한 문제가 발생했는지 알 수는 없지만 코드가 7 줄 밖에 안된다는 점을 감안할 때 상당히 혼란 스럽습니다. – Chuck