CLLocation导致EXC_BAD_ACCESS

时间:2012-05-02 03:01:31

标签: iphone objective-c ios automatic-ref-counting cllocation

此代码在某些时候有效,但有时会因EXC_BAD_ACCESS错误而崩溃。

NSInteger compareDistance(id num1, id num2, void *context) 
{
    int rv;
    //cast parameters from general type
    CLLocation* location = (__bridge_transfer CLLocation *)context;
    Attraction* attr1 = num1;
    Attraction* attr2 = num2;

    //convert to CLLocation objects and calculate distance from user current
    CLLocation* locationAttr1 = 
    [[CLLocation alloc] initWithLatitude:attr1.latitude 
                               longitude:attr1.longitude];
    CLLocation* locationAttr2 = 
    [[CLLocation alloc] initWithLatitude:attr2.latitude 
                               longitude:attr2.longitude];
    CLLocationDistance distance1 = [locationAttr1 distanceFromLocation:location];
    CLLocationDistance distance2 = [locationAttr2 distanceFromLocation:location];

    //compare and rate
    if (distance1 < distance2)
        rv = NSOrderedAscending;
    else if (distance1 > distance2)
        rv = NSOrderedDescending;
    else
        rv = NSOrderedSame;

    return rv;
}

这是一个用于订购NSMutableArray的比较函数:

-(NSMutableArray *)getAttractionsByDistanceInCategory:(int)catID
{
    [self confirmAttractions];

    //set up array and context to prepare for sort
    NSMutableArray *attractionsToSort = [[NSMutableArray alloc] init];
    for (Attraction *a in attractions)
    {
        if ((catID < 0) || (catID >= 0 && a.category == catID))
            [attractionsToSort addObject:a];
    }

    CLLocation* currentLocation = 
        [[CLLocation alloc] initWithLatitude:usersLat longitude:usersLng];

    //conduct sort
    [attractionsToSort sortUsingFunction:compareDistance
                                 context:(__bridge_retained void *)currentLocation];

    return attractionsToSort;
}

嗯。你认为问题可能是ARC吗?我盯着__bridge_retained void *生意。

提前感谢任何建议!

1 个答案:

答案 0 :(得分:3)

__bridge_transfer将所有权转移到目标对象,这可能不是您想要在此处执行的操作,您不希望拥有context的所有权,因为ARC会在认为你完成它的时候尝试发布它,你不希望它这样做。

基本上,您不想在任何地方转让所有权,因此在这两种情况下都只使用__bridge,而且应该可以正常使用。