Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.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
Iphone 在MKMapView中对注释执行操作时发生泄漏_Iphone_Objective C_Mkannotation_Nszombie_Nsmutableset - Fatal编程技术网

Iphone 在MKMapView中对注释执行操作时发生泄漏

Iphone 在MKMapView中对注释执行操作时发生泄漏,iphone,objective-c,mkannotation,nszombie,nsmutableset,Iphone,Objective C,Mkannotation,Nszombie,Nsmutableset,我有一个方法,它接收要在地图视图上显示的注释(自定义PostLocationAnnotation类),并将它们聚集在一起,输出PostLocationAnnotations和LocationGroupAnnotations(每个集群都包含一些PostLocationAnnotations)的MKAnnotation数组。下面是我调用函数的方式(在“updateAnnotations”方法中,当地图的视口更改时调用该方法): annotationsToAdd最初由从服务器检索到但尚未添加到地图的注

我有一个方法,它接收要在地图视图上显示的注释(自定义PostLocationAnnotation类),并将它们聚集在一起,输出PostLocationAnnotations和LocationGroupAnnotations(每个集群都包含一些PostLocationAnnotations)的MKAnnotation数组。下面是我调用函数的方式(在“updateAnnotations”方法中,当地图的视口更改时调用该方法):

annotationsToAdd最初由从服务器检索到但尚未添加到地图的注释填充。因此,我将把应该放在地图上的注释的完整列表传递到clusterAnnotations方法中。以下是该方法的主体:

- (NSArray *)clusterAnnotations:(NSArray *)annotations WithEpsilon:(float)eps andMinPts:(int)minPts
{
    NSMutableSet *D = [[NSMutableSet alloc] initWithCapacity:[annotations count]];
    NSMutableArray *C = [[NSMutableArray alloc] init];

    for (id <MKAnnotation> annotation in annotations)
    {
        if ([annotation isKindOfClass:[PostLocationAnnotation class]])
        {
             NSMutableDictionary *dictEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                              annotation, @"point",
                                              [NSNumber numberWithBool:NO], @"visited",
                                              [NSNumber numberWithBool:NO], @"noise",
                                              [NSNumber numberWithBool:NO], @"clustered", nil];

            [D addObject:dictEntry];

            [dictEntry release];
        } else if ([annotation isKindOfClass:[LocationGroupAnnotation class]])
        {
            for (PostLocationAnnotation *location in [(LocationGroupAnnotation *)annotation locations])
            {
                NSMutableDictionary *dictEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                                  location, @"point",
                                                  [NSNumber numberWithBool:NO], @"visited",
                                                  [NSNumber numberWithBool:NO], @"noise",
                                                  [NSNumber numberWithBool:NO], @"clustered", nil];

                [D addObject:dictEntry];

                [dictEntry release];
            }
        }

    }

    for (NSMutableDictionary *P in D)
    {
        if ([P objectForKey:@"visited"] == [NSNumber numberWithBool:NO])
        {
             [P setValue:[NSNumber numberWithBool:YES] forKey:@"visited"];

             NSMutableSet *N = [[NSMutableSet alloc] initWithSet:[self regionQueryForPoint:P andEpsilon:eps fromList:D]];

             if ([N count] < minPts)
             {
                 [P setValue:[NSNumber numberWithBool:YES] forKey:@"noise"];
             } else {
                 LocationGroupAnnotation *newCluster = [[LocationGroupAnnotation alloc] initWithLocations:nil];
                 [C addObject:newCluster];
                 [self expandDbscanClusterWithPoint:P andRegion:N andCluster:newCluster andEpsilon:eps andMinPts:minPts fromList:D];

                 [newCluster release];
            }

            [N release];

        }
    }


    NSMutableArray *annotationsToAdd = [[[NSMutableArray alloc] initWithCapacity:[annotations count]] autorelease];

    for (NSMutableDictionary *P in D)
    {
        if ([P objectForKey:@"clustered"] == [NSNumber numberWithBool:NO])
        {
            [annotationsToAdd addObject:[P objectForKey:@"point"]];
        }
    }

    for (LocationGroupAnnotation *cluster in C)
    {
        [cluster updateCenterCoordinate];
    }

    [annotationsToAdd addObjectsFromArray:(NSArray *)C];

    [D release];
    [C release];

    return (NSArray *)annotationsToAdd;
}

多年来我一直在分析这个问题,计算引用,观察指针等等,但我就是不知道如何安全地释放这个D集。有人能看到我看不到的东西吗?

你似乎用
[dictEntry release]过度发布了
dictEntry
。当使用带有ObjectsSandKeys的
字典时,您将获得一个自动释放的对象。因此,再次释放它将减少保留计数

编辑:如果您不确定它的工作原理以及实际保留对象的时间,您可能需要查看:

使用名称以“alloc”开头的方法创建对象, “新建”、“复制”或“可变复制”(例如,alloc、newObject或 可变副本)


您似乎过度发布了
dictEntry
,而
[dictEntry release]。当使用带有ObjectsSandKeys的
字典时,您将获得一个自动释放的对象。因此,再次释放它将减少保留计数

编辑:如果您不确定它的工作原理以及实际保留对象的时间,您可能需要查看:

使用名称以“alloc”开头的方法创建对象, “新建”、“复制”或“可变复制”(例如,alloc、newObject或 可变副本)

- (NSArray *)clusterAnnotations:(NSArray *)annotations WithEpsilon:(float)eps andMinPts:(int)minPts
{
    NSMutableSet *D = [[NSMutableSet alloc] initWithCapacity:[annotations count]];
    NSMutableArray *C = [[NSMutableArray alloc] init];

    for (id <MKAnnotation> annotation in annotations)
    {
        if ([annotation isKindOfClass:[PostLocationAnnotation class]])
        {
             NSMutableDictionary *dictEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                              annotation, @"point",
                                              [NSNumber numberWithBool:NO], @"visited",
                                              [NSNumber numberWithBool:NO], @"noise",
                                              [NSNumber numberWithBool:NO], @"clustered", nil];

            [D addObject:dictEntry];

            [dictEntry release];
        } else if ([annotation isKindOfClass:[LocationGroupAnnotation class]])
        {
            for (PostLocationAnnotation *location in [(LocationGroupAnnotation *)annotation locations])
            {
                NSMutableDictionary *dictEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                                  location, @"point",
                                                  [NSNumber numberWithBool:NO], @"visited",
                                                  [NSNumber numberWithBool:NO], @"noise",
                                                  [NSNumber numberWithBool:NO], @"clustered", nil];

                [D addObject:dictEntry];

                [dictEntry release];
            }
        }

    }

    for (NSMutableDictionary *P in D)
    {
        if ([P objectForKey:@"visited"] == [NSNumber numberWithBool:NO])
        {
             [P setValue:[NSNumber numberWithBool:YES] forKey:@"visited"];

             NSMutableSet *N = [[NSMutableSet alloc] initWithSet:[self regionQueryForPoint:P andEpsilon:eps fromList:D]];

             if ([N count] < minPts)
             {
                 [P setValue:[NSNumber numberWithBool:YES] forKey:@"noise"];
             } else {
                 LocationGroupAnnotation *newCluster = [[LocationGroupAnnotation alloc] initWithLocations:nil];
                 [C addObject:newCluster];
                 [self expandDbscanClusterWithPoint:P andRegion:N andCluster:newCluster andEpsilon:eps andMinPts:minPts fromList:D];

                 [newCluster release];
            }

            [N release];

        }
    }


    NSMutableArray *annotationsToAdd = [[[NSMutableArray alloc] initWithCapacity:[annotations count]] autorelease];

    for (NSMutableDictionary *P in D)
    {
        if ([P objectForKey:@"clustered"] == [NSNumber numberWithBool:NO])
        {
            [annotationsToAdd addObject:[P objectForKey:@"point"]];
        }
    }

    for (LocationGroupAnnotation *cluster in C)
    {
        [cluster updateCenterCoordinate];
    }

    [annotationsToAdd addObjectsFromArray:(NSArray *)C];

    [D release];
    [C release];

    return (NSArray *)annotationsToAdd;
}
- (NSSet *)regionQueryForPoint:(NSMutableDictionary *)P andEpsilon:(float)eps fromList:(NSMutableSet *)D
{
    NSMutableSet *N = [[[NSMutableSet alloc] init] autorelease];

    for (NSMutableDictionary *dictEntry in D)
    {
        if ((dictEntry != P) &&
            ([[dictEntry objectForKey:@"point"] isKindOfClass:[PostLocationAnnotation class]]))
        {
            CGPoint p1 = [ffMapView convertCoordinate:[[P objectForKey:@"point"] coordinate] toPointToView:self.view];
            CGPoint p2 = [ffMapView convertCoordinate:[[dictEntry objectForKey:@"point"] coordinate] toPointToView:self.view];

            float dX = p1.x - p2.x;
            float dY = p1.y - p2.y;

            if (sqrt(pow(dX,2)+pow(dY,2)) < eps)
            {
                [N addObject:dictEntry];
            }
        }
    }
    return (NSSet *)N;
}
- (void)expandDbscanClusterWithPoint:(NSMutableDictionary *)P andRegion:(NSMutableSet *)N
                      andCluster:(LocationGroupAnnotation *)cluster
                      andEpsilon:(float)eps
                       andMinPts:(int)minPts
                        fromList:(NSMutableSet *)D
{

    [cluster addAnnotation:(PostLocationAnnotation *)[P objectForKey:@"point"]];
    [P setValue:[NSNumber numberWithBool:YES] forKey:@"clustered"];

    BOOL finished = NO;

    while (!finished)
    {
        finished = YES;

        for (NSMutableDictionary *nextP in N)
        {
            if ([nextP objectForKey:@"visited"] == [NSNumber numberWithBool:NO])
            {
                [nextP setValue:[NSNumber numberWithBool:YES] forKey:@"visited"];

                NSSet *nextN = [self regionQueryForPoint:nextP andEpsilon:eps fromList:D];

                if ([nextN count] >= minPts)
                {
                    [N unionSet:nextN];
                    finished = NO;
                    break;
                }
            }

            if ([nextP objectForKey:@"clustered"] == [NSNumber numberWithBool:NO])
            {
                [cluster addAnnotation:[nextP objectForKey:@"point"]];
                [nextP setValue:[NSNumber numberWithBool:YES] forKey:@"clustered"];
            }

        }
    }

}