0

누군가 누출을 발견하도록 도와주세요. 나는 내 누출 위치를 정말로 모른다. 그래서 나는 여기에 내 코드를 게시하고 누군가가 나를 위해 그것을 발견 할 수 있기를 바랍니다. 누수 도구에서 책임 프레임은 dispatch_semaphore_create입니다. 나는 그것을 부르고 있지 않습니까?Objective-C - 누출 프로필 작성 중 그랜드 센트럴 디스패치가 누출되었다고 표시합니다.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; 

     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 

     dispatch_group_t group = dispatch_group_create(); 

     dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      if ([defaults boolForKey:@"notFirstRunSeminars"]) { 

       BOOL isUpdated = self.seminarsParser.seminarsAreUpdated; 

       if (isUpdated) { 
        DLog(@"Seminars have been updated"); 

        [[NSNotificationCenter defaultCenter] 
        postNotificationName:@"updateSeminarsTable" 
        object:nil]; 

        [[[[[self tabBarController] tabBar] items] objectAtIndex:kSeminarsTabIndex] setBadgeValue:self.seminarsParser.numberOfNewSeminars]; 
        self.seminarsParser.numberOfNewSeminars = nil; 

       } 
      } 
     }); 

     dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      if ([defaults boolForKey:@"notFirstRunCareers"]) { 

       BOOL isUpdated = self.careersParser.careersAreUpdated; 

       if (isUpdated) { 
        DLog(@"Careers have been updated"); 

        [[NSNotificationCenter defaultCenter] 
        postNotificationName:@"updateCareersTable" 
        object:nil]; 

        [[[[[self tabBarController] tabBar] items] objectAtIndex:kCareersTabIndex] setBadgeValue:self.careersParser.numberOfNewCareers]; 
        self.careersParser.numberOfNewCareers = nil; 

       } 
      } 
     }); 

     dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      if ([defaults boolForKey:@"notFirstRunOffices"]) { 

       BOOL isUpdated = [officesParser officesAreUpdated]; 

       if (isUpdated) { 
        DLog(@"Offices have been updated"); 

        [[NSNotificationCenter defaultCenter] 
        postNotificationName:@"updateOfficesTable" 
        object:nil]; 
       } 
      } 
     }); 

     dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

      [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; 

     }); 

    }); 

답변

0

가장 바깥 쪽의 비동기 블록에 그룹을 만들었습니까? 그게 제가 당신이 볼 수있는 유일한 객체입니다. 부수적으로, 그룹은 장면 뒤에 세마포어를 만듭니다 (모든 디스패치 그룹은 내부 디스패치 세마포어 주위의 구문 설탕입니다). 이것이 계기가 그런 식으로보고하는 이유입니다.

3

제로 문제 : 무엇이 유출되고 있습니까?

프로그램을 스캔하는 명백한 누수를 보지 못했기 때문에 다음과 같은 문제가 발생할 수 있습니다. UIKit 객체는 스레드 안전하지 않으며 다른 스레드에서 프로그램에 들어 가지 않으면 기본 스레드에서만 업데이트 할 수 있습니다.

또한 NSNotification 스레드로 게시됩니다.

즉, 모든 UIKit 유형 액세스 및 업데이트가 주 스레드에서 수행되어야 함을 의미합니다. 그리고 네, 정의되지 않은 동작으로 간주해야하는 누수 또는 스레딩 오류가 발생할 수 있습니다.

+0

내 알림은 기본적으로 'reloadData'에 대한 'UITableView'에 대한 호출이므로 메인 스레드에 '게시 알림'호출을 넣어야합니까? –

+1

@Peter Correct. 디버거에서 프로그램의 흐름을보고 싶다면 직접 또는 간접적으로 UIKit 객체를 호출하는 모든 메소드 (직접 메시지, 등록 정보 읽기/쓰기, 알림, 테이블 재로드 등)에 assert ([NSThread isMainThread] 기타.). 실제 구현에서는 UIKit 객체 구현에 들어 가지 않으면 구현이 스레드 안전 * 및 *인지 확인하는 경우 * 구현/속성에 액세스하기 위해 UIKit 객체에 메시지를 보낼 수 있습니다. 또 다른 일반적인 오해는'atomic_property == thread safe'이지만, threadsafe가 아니다. – justin

+0

불행히도 나는 메인 스레드 내부에서 호출을 한 후에 같은 메모리 누수 (Malloc 64 바이트)를 얻고있다. 위에서 보았던 코드는'- applicationWillEnterForeground :'안에 들어 있습니다. 그래서 어플리케이션을 다시 시작할 때마다 메모리 누수가 발생합니다. 그러나 내가 그것을 생각할 때. isUpdated가 'NO'인데도 누수가 발생하기 때문에 메모리 누수의 원인이되는 게시 알림이 아닙니다. 뭐라 구요? –

관련 문제