Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 目标-C–;分析泄漏显示Grand Central Dispatch正在泄漏_Objective C_Cocoa Touch_Memory Leaks_Grand Central Dispatch - Fatal编程技术网

Objective c 目标-C–;分析泄漏显示Grand Central Dispatch正在泄漏

Objective c 目标-C–;分析泄漏显示Grand Central Dispatch正在泄漏,objective-c,cocoa-touch,memory-leaks,grand-central-dispatch,Objective C,Cocoa Touch,Memory Leaks,Grand Central Dispatch,有人能帮我找出漏洞吗。我真的不知道我的漏洞在哪里。所以我会在这里发布我的代码,希望有人能帮我发现它。在泄漏工具中,它说负责的帧是我没有调用的dispatch\u semaphore\u create dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [[UIApplication sharedApplication] setNetworkActivityIndicat

有人能帮我找出漏洞吗。我真的不知道我的漏洞在哪里。所以我会在这里发布我的代码,希望有人能帮我发现它。在泄漏工具中,它说负责的帧是我没有调用的
dispatch\u semaphore\u create

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];

        });

    });

零问题:泄露了什么

由于我在扫描您的程序时没有看到明显的泄漏,因此最可能的问题是:UIKit对象不是线程安全的,只能从主线程更新,除非它们从另一个线程进入您的程序

还要注意,
NSNotification
s被发布在调用线程上


这意味着所有UIKit类型的访问和更新都需要在主线程上执行。是的,它会引入泄漏或线程错误,你应该把它看作是未定义的行为。

零问题:什么是泄露?

由于我在扫描您的程序时没有看到明显的泄漏,因此最可能的问题是:UIKit对象不是线程安全的,只能从主线程更新,除非它们从另一个线程进入您的程序

还要注意,
NSNotification
s被发布在调用线程上


这意味着所有UIKit类型的访问和更新都需要在主线程上执行。是的,这可能会导致泄漏或线程错误,你应该把它们看作是未定义的行为。

在你完成它之后,你在哪里释放组,因为你在最外面的异步块中创建了一个组?这是我能看到你创建的唯一一个没有被正确释放的对象。顺便说一句,一个组在幕后创建了一个信号量(调度组实际上就是内部调度信号量周围的一些语法糖),这就是instruments以这种方式报告它的原因。

既然您在最外层的异步块中创建了一个组,那么在处理完组后,您在哪里释放它?这是我能看到你创建的唯一一个没有被正确释放的对象。顺便说一句,一个组在幕后创建了一个信号量(调度组实际上只是内部调度信号量周围的一些语法糖),这就是instruments以这种方式报告它的原因。

因此,由于我的通知本质上是对“UITableView”的调用以“reloadData”,我应该把“post notification”放在主线程中的调用?@Peter正确。如果要查看程序在调试器中的流动情况,请添加
assert([NSThread isMainThread])
调用所有直接或间接调用UIKit对象(直接消息、属性读/写、通知、表重新加载等)的方法。实际上,如果您确保您的实现是线程安全的,并且没有进入UIKit对象的实现,则可以向UIKit对象发送消息以访问您的实现/属性。另一个常见的误解是
atomic_property==thread safe
,但它不是threadsafe。不幸的是,在将调用放在主线程中之后,我得到了相同的内存泄漏(Malloc 64字节)。上面看到的代码放在
-applicationWillEnterForeground:
中,因此每次我恢复应用程序时,都会出现内存泄漏。但是当我想到它的时候。不是发布通知导致内存泄漏,因为即使
isUpdated
NO
,我也会收到泄漏。给出了什么?这是在删除所有
分派\uucode>/GCD调用之后?您需要在安排完成回调后释放组。因此,由于我的通知本质上是对“UITableView”的调用,以“reloadData”,我应该将“post notification”调用放在主线程中。@Peter Correct。如果要查看程序在调试器中的流动情况,请添加
assert([NSThread isMainThread])
调用所有直接或间接调用UIKit对象(直接消息、属性读/写、通知、表重新加载等)的方法。实际上,如果您确保您的实现是线程安全的,并且没有进入UIKit对象的实现,则可以向UIKit对象发送消息以访问您的实现/属性。另一个常见的误解是
atomic_property==thread safe
,但它不是threadsafe。不幸的是,在将调用放在主线程中之后,我得到了相同的内存泄漏(Malloc 64字节)。上面看到的代码放在
-applicationWillEnterForeground:
中,因此每次我恢复应用程序时,都会出现内存泄漏。但是当我想到它的时候。不是发布通知导致内存泄漏,因为即使
isUpdated
NO
,我也会收到泄漏。给出了什么?这是在删除所有的
分派\ucode>/GCD调用之后?您需要在安排完成回调后释放组。