Swift 프로그램에서 autoreleasepool을 사용해야합니까?


95

의 17 페이지에 이 WWDC14 발표 , 그것은 말한다

Objective-C로 작업하십니까? 여전히 자동 릴리스 풀을 관리해야합니다.
autoreleasepool {/ * code * /}

그게 무슨 뜻입니까? 내 코드베이스에 Objective-C 파일이 없다면 autoreleasepool {}불필요 하다는 뜻 입니까?

관련된 질문의 답변 , 예를 들어이 autoreleasepool유용 할 수 있습니다 :

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

위의 코드가 autoreleasepool드롭 된 상태에서 Swift로 번역 되면 Swift는 number변수가 첫 번째 이후에 릴리스되어야 한다는 것을 알 수있을만큼 똑똑 }할까요 (다른 언어처럼)?


1
autoreleasepoolSwift 에는 문서가없는 것 같습니다 . 나는 귀하의 질문을 확장하고 개발자 포럼에서 질문했습니다 .
아론 Brager

답변:


197

autoreleasepool패턴은 autorelease객체를 반환 할 때 Swift에서 사용됩니다 (Objective-C 코드 또는 Cocoa 클래스를 사용하여 생성됨). autoreleaseSwift 의 패턴은 Objective-C에서와 매우 유사합니다. 예를 들어, 다음 Swift 변환을 고려하십시오 (인스턴스화 NSImage/ UIImage객체).

func useManyImages() {
    let filename = pathForResourceInBundle

    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

Instruments에서 이것을 실행하면 다음과 같은 할당 그래프가 표시됩니다.

autoreleasepool 사용

그러나 자동 릴리스 풀없이 수행하면 최대 메모리 사용량이 더 높다는 것을 알 수 있습니다.

autoreleasepool없이

autoreleasepool당신이 목표 - C에서 할 수 있었던 것처럼, 오토 릴리즈 객체가 스위프트에 해제 될 때 명시 적으로 관리 할 수 있습니다.

참고 : Swift 네이티브 개체를 처리 할 때 일반적으로 자동 릴리스 개체를받지 않습니다. 이것이 프레젠테이션에서 "Objective-C로 작업"할 때만이 기능이 필요하다는 경고를 언급 한 이유입니다.하지만이 점에 대해 Apple이 더 명확했으면합니다. 하지만 Objective-C 객체 (Cocoa 클래스 포함)를 다루는 경우 자동 해제 객체 일 수 있습니다.이 경우 Objective-C @autoreleasepool패턴 의 Swift 변환 이 여전히 유용합니다.


2
이 모든 질문에 대해 자신의 클래스를 작성하고 println에서 수행하도록 deinit할 수 있으며 객체가 할당 해제 된시기를 정확하게 확인하는 것이 매우 쉬워집니다. 또는 Instruments에서 관찰하십시오. 귀하의 질문에 대한 답변으로 Swift 객체는 +1 보유 횟수 (자동 해제 객체가 아님)가있는 함수에서 반환되며 호출자는 해당 시점에서 소유권을 원활하게 관리합니다 (예 : 반환 된 객체가 범위를 벗어나는 경우, 자동 해제 풀에 배치되지 않고 즉시 할당 해제됩니다.
Rob

3
@StevenHernandez 자동 릴리스 풀은 누수와 거의 관련이 없습니다. 릴리스되지 않은 개체로 인해 누출이 발생합니다. 반면에 Autorelease 풀은 풀이 배수 될 때까지 릴리스가 연기되는 개체 모음 일뿐입니다. 풀은 무언가의 할당 해제 여부를 제어하는 ​​것이 아니라 단순히 그러한 할당 해제의 타이밍을 제어합니다. 맵 뷰를 다시 보면 캐싱이 수행하는 작업 (메모리를 사용하지만 실제 누수가 아님)을 제어 할 수 없으며 실제 누수가 있으면 아무것도 할 수 없습니다. UIKit의 무작위, 겸손한 누출).
Rob

2
@matt 네, 비슷한 행동을 보았습니다. 그래서 나는 NSImage/ UIImageobjects를 가지고 운동을 반복 했고 문제를 더 일관되게 나타 냈습니다. (솔직히 이것은 더 일반적인 문제의 예입니다. 왜냐하면 최대 메모리 사용량은 더 큰 객체를 다룰 때만 문제가되기 때문입니다. 이미지의 크기를 조정하는 루틴). 또한 명시 적으로 autorelease 개체를 만든 Objective-C 코드를 호출하는 동작을 재현했습니다. 오해하지 마세요. Objective-C보다 Swift에서 autorelease 풀이 덜 필요하다고 생각하지만 여전히 수행 할 역할이 있습니다.
Rob

1
작동하는 예를 찾았습니다! NSBundle을 pathForResource:ofType:반복해서 호출하십시오 .
matt

1
pathForResource:ofType:예제는 더 이상 Xcode 6.3 / Swift 1.2에서 작동하지 않습니다. :)
matt

4

동등한 Objective-C 코드에서 사용한다면 Swift에서 사용할 것입니다.

Swift는 number 변수가 첫 번째 이후에 해제되어야한다는 것을 알 정도로 똑똑 할 것입니다.}

Objective-C가 작동하는 경우에만. 둘 다 Cocoa 메모리 관리 규칙에 따라 작동합니다.

물론 ARC는 number루프의 반복이 끝날 때 범위를 벗어나는 것을 알고 있으며 이를 유지하면 그곳에서 해제 할 것입니다. 그러나 자동 해제 된 인스턴스를 반환했거나 반환 -[NSNumber numberWithInt:] 하지 않았을 있기 때문에 객체가 자동 해제되었는지 여부는 알려주지 않습니다 . 의 소스에 대한 액세스 권한이 없기 때문에 알 수있는 방법이 없습니다 -[NSNumber numberWithInt:].


1
Swift가 Objective-C와 동일하게 작동한다면 프레젠테이션에서 "Working with Objective-C?"라고 언급 한 이유는 무엇입니까? 구체적으로 특별히?
Ethan

9
@Ethan 네이티브 Swift 객체는 자동 해제 객체가 아니며 autoreleasepool구성은 완전히 불필요합니다. 그러나 Swift 코드가 Objective-C 객체 (Cocoa 객체 포함)를 처리하는 경우 자동 릴리스 패턴을 따르므로 autoreleasepool구성이 유용합니다.
Rob

"자동 해제 풀을 사용하면 Swift에서 자동 해제 개체가 할당 해제되는시기를 명시 적으로 관리 할 수 ​​있습니다."라는 메시지가 표시됩니다.하지만 왜 그렇게해야합니까? 컴파일러가 나를 대신해주는 이유는 무엇입니까? 거대한 문자열 조작의 엄격한 루프에서 VM이 지붕을 통과하지 못하도록 자체 자동 릴리스 풀을 추가해야했습니다. 어디에 추가해야할지 분명했고 완벽하게 작동했습니다. 왜 컴파일러가 할 수 없습니까? 컴파일러를 더 똑똑하게 만들어서 좋은 일을 할 수 있을까요?
vonlost
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.