문제

내가 이해하는 바에 따르면, 할당, 새로운, 또는 복사 수동으로 해제해야 합니다.예를 들어:

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가 객체로 전송될 때마다 가장 안쪽의 자동 릴리스 풀에 추가됩니다.풀이 비워지면 풀의 모든 개체에 -release를 보냅니다.

자동 릴리스 풀은 단순히 "나중에"까지 릴리스 전송을 연기할 수 있는 편의를 제공합니다."나중에"는 여러 위치에서 발생할 수 있지만 Cocoa GUI 앱에서 가장 일반적인 것은 현재 실행 루프 주기가 끝날 때입니다.

다른 팁

NSAutorelease풀:배수 대풀어 주다

의 기능부터 drain 그리고 release 혼란을 야기하는 것 같으니 여기에서 명확히 하는 것이 좋습니다. 문서...).

엄밀히 말하면 큰 그림의 관점에서 보면 drain ~이다 ~ 아니다 에 해당 release:

참조 계산 환경에서는 drain 와 동일한 작업을 수행합니다. release, 따라서 두 개는 그런 의미에서 동일합니다.강조하자면, 이는 다음을 의미합니다. ~ 아니다 사용하는 경우 수영장 누출 drain 오히려 release.

가비지 수집 환경에서는 release 작동하지 않습니다.따라서 효과가 없습니다. drain, 반면에 "필요한 경우 수집해야 한다"는 힌트가 수집기에 포함되어 있습니다.따라서 가비지 수집 환경에서는 다음을 사용합니다. drain 시스템 균형 수집을 돕습니다.

이미 지적했듯이 두 번째 코드 조각은 정확합니다.

나는 모든 환경(참조 계산, GC, ARC)에서 작동하고 배수/릴리스 혼란을 피하는 자동 릴리스 풀을 사용하는 보다 간결한 방법을 제안하고 싶습니다.

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

위의 예에서 다음 사항에 유의하세요. @autoreleasepool 차단하다.이것은 문서화되어 있습니다. 여기.

아니, 넌 틀렸어.문서에는 GC가 아닌 경우 -drain이 -release와 동일하다고 명시되어 있습니다. 즉, NSAutoreleasePool은 ~ 아니다 유출되다.

내가 Apple에서 읽은 내용은 다음과 같습니다."자동 해제 풀 블록이 끝나면 블록 내에서 자동 해제 메시지를 받은 객체에 해제 메시지가 전송됩니다. 객체는 블록 내에서 자동 해제 메시지가 전송될 때마다 해제 메시지를 받습니다."

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

객체에 릴리스 대신 자동 릴리스를 보내면 적어도 풀 자체가 비워질 때까지 해당 객체의 수명이 연장됩니다(객체가 이후에 유지되는 경우 더 길어질 수 있음).객체는 동일한 풀에 여러 번 들어갈 수 있으며, 이 경우 풀에 들어갈 때마다 해제 메시지를 받습니다.

예, 아니오.가비지 수집(메모리 관리 아님) 환경에서 이 작업을 실행한 경우 릴리스 대신 드레인을 사용하여 문자열 메모리를 해제하지만 NSAutoreleasePool 개체를 메모리로 "누출"하게 됩니다.이 "누출"은 단순히 GC 아래에 강력한 포인터가 없는 다른 개체처럼 NSAutoreleasePool의 인스턴스를 "접근할 수 없게" 만들고 다음 번에 GC가 실행될 때 개체가 정리됩니다. 이는 호출 직후일 수 있습니다. -drain:

물을 빼다

가비지 수집 환경에서 마지막 수집 이후 할당된 메모리가 현재 임계값보다 큰 경우 가비지 수집을 트리거합니다.그렇지 않으면 릴리스로 동작합니다....가비지 수집 환경에서 이 메서드는 궁극적으로 다음을 호출합니다. objc_collect_if_needed.

그렇지 않으면 방법과 비슷합니다. -release GC가 아닌 경우에도 작동합니다. 그렇습니다.다른 사람들이 말했듯이, -release GC에서는 작동하지 않으므로 GC에서 풀이 제대로 작동하는지 확인하는 유일한 방법은 다음과 같습니다. -drain, 그리고 -drain 비 GC에서는 다음과 똑같이 작동합니다. -release GC가 아닌 경우에도 그 기능을 더 명확하게 전달합니다.

"new, alloc 또는 init로 호출되는 모든 것"이라는 명령문에는 "init"가 포함되어서는 안 됩니다(그러나 "복사"는 포함되어야 함). "init"는 메모리를 할당하지 않고 객체(생성자)만 설정하기 때문입니다. 패션).할당된 객체를 받았고 함수가 init만 호출했다면 해당 객체를 해제하지 않을 것입니다.

- (void)func:(NSObject*)allocd_but_not_init
{
    [allocd_but_not_init init];
}

이는 이미 시작한 것보다 더 많은 메모리를 소비하지 않습니다(init가 객체를 인스턴스화하지 않는다고 가정하지만 어쨌든 이에 대한 책임은 없습니다).

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