0

是否有人可以幫助我發現泄漏。我真的不知道我的泄漏在哪裏。所以我會在這裏發佈我的代碼,希望有人能爲我發現它。在泄漏儀器中,它表示負責的框架是dispatch_semaphore_create,我不打電話?Objective-C - 剖析泄漏顯示Grand Central Dispatch正在泄漏

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

因此,因爲我的通知基本上是調用'UITableView'到'reloadData',我應該在主線程中放置「發佈通知」調用? –

+1

@彼得更正。如果你想看看你的程序如何在調試器中流動,可以爲所有那些直接或間接調用UIKit對象的方法添加assert([NSThread isMainThread]);(直接消息,屬性讀/寫,通知,表重載,等等。)。在實踐中,如果你確保你的實現是線程安全的,並且如果它們沒有進入UIKit對象的實現,你可以*發送UIKit對象來訪問你的*實現/屬性。另一個常見的誤解是'atomic_property ==線程安全性',但它不是線程安全的。 – justin

+0

不幸的是,我在調用主線程後收到了相同的內存泄漏(Malloc 64字節)。上面看到的代碼放在' - applicationWillEnterForeground:'內部,所以每當我恢復應用程序時,都會發生內存泄漏。但是當我想到它時。這不是發佈通知導致內存泄漏,因爲即使'isUpdated'爲'NO',我也會泄漏內存。是什麼賦予了? –