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',我也会泄漏内存。是什么赋予了? –