내가 알기로는 alloc , new 또는 copy로 만든 모든 것은 수동으로 해제해야합니다. 예를 들면 :
int main(void) {
NSString *string;
string = [[NSString alloc] init];
/* use the string */
[string release];
}
내 질문은 이것이 유효하지 않습니까? :
int main(void) {
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
NSString *string;
string = [[[NSString alloc] init] autorelease];
/* use the string */
[pool drain];
}
답변
예, 두 번째 코드 조각은 완벽하게 유효합니다.
-autorelease가 객체로 전송 될 때마다 가장 안쪽의 autorelease 풀에 추가됩니다. 풀이 배수되면 풀의 모든 오브젝트에 -release를 전송합니다.
Autorelease 풀은 단순히 “나중에”까지 보내기를 연기 할 수있는 편리함을 제공합니다. 이 “나중에”는 여러 곳에서 발생할 수 있지만 Cocoa GUI 앱에서 가장 일반적인 것은 현재 실행 루프주기의 끝입니다.
답변
NSAutoreleasePool : 드레인 대 릴리스
의 기능 때문에 drain
하고 release
혼란을 일으키는 것 같다, 그것은 (이이 덮여 있지만 가치는 여기에 명확히 수 있습니다 문서 …).
엄밀히 큰 그림의 관점에서 말하는 것은 drain
입니다 하지 동일합니다 release
:
참조 횟수가 계산 된 환경에서는와 drain
동일한 작업을 수행 release
하므로 두 가지가 동일한 의미입니다. 강조하기 위해,이 방법은 당신이 할 수 없습니다 당신이 사용하는 경우 풀을 누설 drain
보다는 release
.
가비지 수집 환경에서는 작동 release
하지 않습니다. 따라서 효과가 없습니다. drain
반면에에는 수집가에게 “필요한 경우 수집”해야한다는 힌트가 포함되어 있습니다. 따라서 가비지 수집 환경에서를 사용 drain
하면 시스템 균형 수집 스위핑이 도움이됩니다.
답변
이미 지적했듯이 두 번째 코드 조각이 정확합니다.
모든 환경 (ref counting, GC, ARC)에서 작동하고 드레인 / 릴리스 혼동을 피하는 autorelease 풀을 사용하는보다 간결한 방법을 제안하고 싶습니다.
int main(void) {
@autoreleasepool {
NSString *string;
string = [[[NSString alloc] init] autorelease];
/* use the string */
}
}
위의 예에서 @autoreleasepool 블록에 유의하십시오 . 여기에 설명되어 있습니다 .
답변
아니, 넌 틀렸어. 문서에는 비 GC에서 -drain이 -release와 동일하므로 NSAutoreleasePool이 유출 되지 않는다고 명시되어 있습니다.
답변
내가 Apple에서 읽은 내용 : “자동 해제 풀 블록이 끝날 때 블록 내에서 자동 해제 메시지를받은 객체는 해제 메시지를받습니다. 객체는 블록 내에서 자동 해제 메시지를 보낼 때마다 해제 메시지를받습니다. “
답변
객체에 릴리즈 대신 자동 릴리즈를 보내면 적어도 풀 자체가 비워 질 때까지 해당 객체의 수명이 연장됩니다 (객체가 나중에 유지되는 경우 더 길어질 수 있음). 오브젝트는 동일한 풀에 여러 번 배치 될 수 있으며,이 경우 풀에 배치 될 때마다 릴리스 메시지를 수신합니다.
답변
예, 아니오. 문자열 메모리를 해제하지만 가비지 수집 (메모리 관리가 아님) 환경에서이를 실행하면 해제 대신 drain을 사용하여 NSAutoreleasePool 개체를 메모리로 “누수”합니다. 이 “누수”는 GC 아래에 강력한 포인터가없는 다른 객체와 마찬가지로 NSAutoreleasePool의 인스턴스를 “도달 할 수 없음”으로 만들고 다음에 GC가 실행될 때 객체가 정리됩니다. 이는 다음을 호출 한 직후 일 수 있습니다 -drain
.
배수
가비지 수집 환경에서 마지막 수집 이후 할당 된 메모리가 현재 임계 값보다 큰 경우 가비지 수집을 트리거합니다. 그렇지 않으면 릴리스로 작동합니다. … 가비지 수집 환경에서이 메서드는 궁극적으로
objc_collect_if_needed
.
그렇지 않으면 -release
비 GC에서 작동 하는 방식과 유사 합니다. 다른 사람이 언급했듯이, -release
GC 통해입니다 아래에있는 유일한 방법은 반드시 풀 제대로 작동 할 수 있도록 GC 아래에 어떤 조합이없는 -drain
, 그리고 -drain
비 GC에서 정확히 같은 작품 -release
이 아닌 GC에서, 거의 틀림없이 더 명확로서의 기능을 통신 잘.
“init”는 메모리를 할당하지 않고 객체 (생성자) 만 설정하기 때문에 “new, alloc 또는 init로 호출 된 모든 것”에는 “init”가 포함되지 않아야합니다 (하지만 “복사”는 포함되어야 함). 패션). 할당 된 객체를 받고 함수가 init 만 호출 한 경우 해제하지 않습니다.
- (void)func:(NSObject*)allocd_but_not_init
{
[allocd_but_not_init init];
}
그것은 이미 시작한 것보다 더 많은 메모리를 소비하지 않습니다 (init가 객체를 인스턴스화하지 않는다고 가정하지만 어쨌든 당신은 책임이 없습니다).
