Objective-C ARC 멀티 스레딩 iOS 앱에서 특정 메모리 누수를 수정할 수 없습니다.

konran

계측기가 다음 방법에 대해보고하는 메모리 누수를 수정하기 위해 거의 뼈를 부러 뜨리고 있습니다.

- (BOOL)moveCloudFileToLocal: (NSString*)cloudFilePath error: (NSError**)error
{
    // each variable starting with an underscore is an ivar
    BOOL    bSuccess = NO;

    @autoreleasepool
    {
        NSArray*    paths        = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString*   docPathLocal = [paths objectAtIndex:0];
        NSURL*      sourceURL    = [NSURL fileURLWithPath:cloudFilePath];               // => LEAKING!!!
        NSString*   destFileName = sourceURL.lastPathComponent;
        NSURL*      destFileURL  = [[NSURL fileURLWithPath:docPathLocal]
                                            URLByAppendingPathComponent:destFileName];  // => LEAKING!!!
        NSArray*    arrArgs      = @[ sourceURL, destFileURL ];                         // => LEAKING!!!
        NSThread*   thread       = [[NSThread alloc] initWithTarget: self
                                                           selector: @selector(threadMoveCloudFileToLocal:)
                                                             object: arrArgs];

        _threadCloud = thread;
        [_threadCloud start];
    }

    [self waitForMovingThreadToFinish];

    if (error != nil)
        *error = _retError;

    bSuccess = (_retError == nil);

    return bSuccess;
}

Instruments는 arrArgs, sourceURL 및 destFileURL이 다음과 같이 루트 누출을 일으킨다 고 말합니다.

iELANA / Instruments 그래픽 루트 누출 화면 캡처

더 많은 정보는 Instruments의이 출력이지만 결과에 익숙하지 않으므로 누수를 해결하기 위해 어떤 조치를 취해야하는지 알 수 없습니다.

iELANA / Instruments 구조적 루트 누출 화면 캡처

다음 세 가지 변수를 다르게 작성하려고 추가로 시도했습니다.

NSURL __autoreleasing*      sourceURL...;
NSURL __autoreleasing*      destFileURL...;
NSArray __autoreleasing*    arrArgs...;

불행히도 이것은 아무것도 변경하지 않으며 동일한 방식으로 계속 누출됩니다. 좋아요, 그것은 충돌하지 않지만 누출되어 수리하고 싶습니다. iOS 7.0.3과 함께 iPhone Simulator를 사용하여 OS X 10.9.5에서 Xcode 6.1.1을 사용하고 있습니다.

여기에 힌트가 있습니까?

요청에 따라 편집, 추가 코드 부분 :

- (void)threadMoveCloudFileToLocal: (NSArray*)args
{
    //  args:
    //      1:  sourceURL   = iCloud file
    //      2:  destFileURL = local file
    //
    _bgTaskExpired = NO;

    @autoreleasepool
    {
        UIBackgroundTaskIdentifier  bgTask = [[UIApplication sharedApplication]
                                              beginBackgroundTaskWithExpirationHandler:^{ self->_bgTaskExpired = YES; }];

        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

        if ([args count] != 2)
            goto finished;

        {
            NSError*            lastError   = nil;
            NSURL*              sourceURL   = [args objectAtIndex:0];   // sourceURL is the iCloud file
            __block NSURL*      destFileURL = [args objectAtIndex:1];   // destFileURL is the local file
            __block NSError*    theError    = nil;
            __block BOOL        bSuccess    = NO;

            _retError  = nil;
            _fileCoord = [[NSFileCoordinator alloc] initWithFilePresenter:self];
            [_fileCoord coordinateWritingItemAtURL: sourceURL
                                           options: NSFileCoordinatorWritingForDeleting
                                             error: &lastError
                                        byAccessor: ^(NSURL* newURL)
            {
                NSFileManager*  fileManager = [[NSFileManager alloc] init];

                if (AfxGetApp().numVersion >= 6.0)
                {
                    bSuccess = [fileManager setUbiquitous:NO itemAtURL:newURL destinationURL:destFileURL error:&theError];

                    if (bSuccess)
                    {
                        theError = nil;
                        bSuccess = [fileManager evictUbiquitousItemAtURL:newURL error:&theError];

                        if (!bSuccess && [iCloudSupport errorIsFileNotFound:theError])
                        {
                            bSuccess = YES;
                            theError = nil;
                        }
                    }
                }
                else
                {
                    // on iPad1 with iOS 5.1.1 it is hanging with the above procedure
                    //...code not being shared, not relevant
                }

                if (bSuccess)
                    [self removeFilePathFromContainers:sourceURL.path];
            }];
            _fileCoord = nil;

            if (lastError == nil && theError != nil)
                lastError = theError;

            if (!bSuccess && lastError == nil)
                lastError = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorUnknown userInfo:nil];

            _retError = lastError;
        }

finished:
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        [[UIApplication sharedApplication] endBackgroundTask:bgTask];
    }   // end @autoreleasepool

    [NSThread exit];
}

- (void)waitForMovingThreadToFinish
{
    while (_threadCloud && ![_threadCloud isFinished])
    {
        // Wait for the thread to finish.
        [NSThread sleepForTimeInterval:0.1];
    }
}

BTW : 정적 분석기는 내 코드에서 단일 경고가 아니라 아무것도 찾지 못합니다. 동적으로 실행될 때만 나타납니다. 코드는 iOS 6과 iOS 7이 막 나왔을 때의 것입니다. 그 당시 이전 SDK에서는 불만이 없었습니다. evictUbiquitousItemAtURL : 조차도 현재 문서에서와 같이 조정 된 쓰기와 함께 사용할 때 문서에서 교착 상태로 표시되지 않았습니다. iOS 5.1.1에서 실행 되었음에도 불구하고 교착 상태가 발생하지 않았기 때문에 별도의 조건부 else 부분이 있습니다.

편집 : 더 명확하게하기 위해 추가 악기 출력

몇 줄의 코드를 변경하기 전에 Instruments에서이 코드보기를 가져 왔습니다.

iELANA / Instruments 루트 누출 화면 캡처의 첫 번째 코드보기

스레드 생성 문 내에서 객체로 전달되는 매개 변수 배열을 구축하기 위해 몇 줄의 코드를 변경 한 후에는 정확히 NSArray 인스턴스화 줄만 누수되기 때문에 Instruments에서 상당히 흥미로워 보입니다. 불행히도 나는 그 이유를 이해하지 못하고 그것을 고치는 방법을 모릅니다.

iELANA / Instruments 루트 누수 화면 캡처의 두 번째 코드보기

TomSwift

에 대한 호출을 제거해야합니다 [NSThread exit]. 스레드의 루트 자동 해제 풀이 드레 이닝되는 것을 방지합니다.

+ (void) exit말할 문서 :

이 메서드를 호출하면 스레드가 실행 중에 할당 한 리소스를 정리할 수있는 기회를주지 않으므로 피해야합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Objective-C (iOS) : 레이블의 텍스트를 수정할 수 없습니다.

분류에서Dev

C에서 메모리 누수를 찾을 수 없습니다.

분류에서Dev

C # 멀티 스레딩은 변수를 메서드에 전달하여 원래 값을 유지합니다.

분류에서Dev

iOS에서 ARC 메모리 누수를 방지하는 방법

분류에서Dev

멀티 스레딩의 정적 변수

분류에서Dev

그리드 엔진 / 멀티 스레딩 / 멀티 코어 / 멀티 CPU : 최적의 스레드 수를 결정하는 방법은 무엇입니까?

분류에서Dev

줄리아 : 멀티 스레딩을 할 수 있습니까?

분류에서Dev

JAVA 멀티 스레딩, 메모리 누수, 가비지 수집기

분류에서Dev

멀티 스레딩-다른 클래스의 메서드간에 변수 전달

분류에서Dev

C ++ 멀티 스레딩-공유 변수에 대한 쓰기 처리 방법

분류에서Dev

특정 디렉토리에 액세스 할 수 없습니다

분류에서Dev

멀티 스레딩을 지원하기위한 유틸리티 방법 수정

분류에서Dev

OpenCL : 정수를 상수 메모리에 전달할 수 없습니다.

분류에서Dev

C ++ / Objective-C ++ 코드에서 중단 점을 설정할 수 없습니다.

분류에서Dev

Django 테스트에서 메모리 누수를 어떻게 수정합니까?

분류에서Dev

멀티 스레딩을 할 때 첫 번째 스레드에서 한 번만 메시지를 보낼 수 있으며 그 후 첫 번째 스레드에서 메시지를 보낼 수 없습니다.

분류에서Dev

C ++에서 클래스의 변수를 수정할 수 없습니다.

분류에서Dev

Swift에서 Objective-C 속성을 설정할 수 없습니다.

분류에서Dev

multivalueconverter를 지정해야하므로 멀티 바인딩을 설정할 수 없습니다. WPF

분류에서Dev

VBScript에서 특정 레지스트리 키를 찾을 수 없습니다.

분류에서Dev

블록이있는 함수 호출이 있고 결국 null로 설정되지 않은 객체를 iOS (ARC)에서 만들 수 있습니까? 메모리 누수가 있습니까?

분류에서Dev

C에서 메모리를 해제 할 수 없습니다.

분류에서Dev

Python : 변수를 한 번 설정하는 멀티 스레딩

분류에서Dev

함수를 호출 할 때 C ++에서 사용자 정의 클래스로 메모리를 읽을 수 없음

분류에서Dev

MSMQ 메시지 멀티 캐스트 : 다른 컴퓨터에서 메시지를받을 수 없습니다.

분류에서Dev

턴 기반 멀티 플레이어 앱은 두 플레이어 모두 턴을 할 수 없습니다.

분류에서Dev

IOS의 Custom WifiStatus 파일에서 메모리 누수를 수정하는 방법

분류에서Dev

C ++에서 멀티 스레딩시 "일치하는 함수 호출 없음"오류

분류에서Dev

AttachedBehavior에서 DependencyPropertyDescriptor AddValueChanged 메모리 누수를 어떻게 수정할 수 있습니까?

Related 관련 기사

  1. 1

    Objective-C (iOS) : 레이블의 텍스트를 수정할 수 없습니다.

  2. 2

    C에서 메모리 누수를 찾을 수 없습니다.

  3. 3

    C # 멀티 스레딩은 변수를 메서드에 전달하여 원래 값을 유지합니다.

  4. 4

    iOS에서 ARC 메모리 누수를 방지하는 방법

  5. 5

    멀티 스레딩의 정적 변수

  6. 6

    그리드 엔진 / 멀티 스레딩 / 멀티 코어 / 멀티 CPU : 최적의 스레드 수를 결정하는 방법은 무엇입니까?

  7. 7

    줄리아 : 멀티 스레딩을 할 수 있습니까?

  8. 8

    JAVA 멀티 스레딩, 메모리 누수, 가비지 수집기

  9. 9

    멀티 스레딩-다른 클래스의 메서드간에 변수 전달

  10. 10

    C ++ 멀티 스레딩-공유 변수에 대한 쓰기 처리 방법

  11. 11

    특정 디렉토리에 액세스 할 수 없습니다

  12. 12

    멀티 스레딩을 지원하기위한 유틸리티 방법 수정

  13. 13

    OpenCL : 정수를 상수 메모리에 전달할 수 없습니다.

  14. 14

    C ++ / Objective-C ++ 코드에서 중단 점을 설정할 수 없습니다.

  15. 15

    Django 테스트에서 메모리 누수를 어떻게 수정합니까?

  16. 16

    멀티 스레딩을 할 때 첫 번째 스레드에서 한 번만 메시지를 보낼 수 있으며 그 후 첫 번째 스레드에서 메시지를 보낼 수 없습니다.

  17. 17

    C ++에서 클래스의 변수를 수정할 수 없습니다.

  18. 18

    Swift에서 Objective-C 속성을 설정할 수 없습니다.

  19. 19

    multivalueconverter를 지정해야하므로 멀티 바인딩을 설정할 수 없습니다. WPF

  20. 20

    VBScript에서 특정 레지스트리 키를 찾을 수 없습니다.

  21. 21

    블록이있는 함수 호출이 있고 결국 null로 설정되지 않은 객체를 iOS (ARC)에서 만들 수 있습니까? 메모리 누수가 있습니까?

  22. 22

    C에서 메모리를 해제 할 수 없습니다.

  23. 23

    Python : 변수를 한 번 설정하는 멀티 스레딩

  24. 24

    함수를 호출 할 때 C ++에서 사용자 정의 클래스로 메모리를 읽을 수 없음

  25. 25

    MSMQ 메시지 멀티 캐스트 : 다른 컴퓨터에서 메시지를받을 수 없습니다.

  26. 26

    턴 기반 멀티 플레이어 앱은 두 플레이어 모두 턴을 할 수 없습니다.

  27. 27

    IOS의 Custom WifiStatus 파일에서 메모리 누수를 수정하는 방법

  28. 28

    C ++에서 멀티 스레딩시 "일치하는 함수 호출 없음"오류

  29. 29

    AttachedBehavior에서 DependencyPropertyDescriptor AddValueChanged 메모리 누수를 어떻게 수정할 수 있습니까?

뜨겁다태그

보관