【发布时间】:2012-11-01 22:27:28
【问题描述】:
我遇到了块和弱引用的问题,我在 ARC 下。我建立了一个类,它是一个免费项目,它是一种简单的 Google Directions API 包装器,您可以在这里下载它:link to the project
我在视图控制器中使用它,问题是使用它后视图控制器没有被释放。我想这是这个对象的一个问题,因为如果我将它注释掉或设置为 nil 一切正常。我不明白retain cycle在哪里,当然我设置为weak self,这是我使用它的视图控制器的方法:
- (void) getDirections{
__weak RouteMapViewController * weakSelf = self;
self.routeObject = [[RouteDirectionsObject alloc]init];
[self.mapView removeAnnotations:self.mapView.annotations];
[self.mapView removeOverlays:self.mapView.overlays];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
[_routeObject createDirectionRequestWithStartPoint:weakSelf.startPoint
andEndPoint:weakSelf.endPoint
withCallBackBlock:^(NSError *error, NSDictionary *routeDistance, NSDictionary *routeDuration, MKPolyline *routePolyline, NSArray *routes, NSArray *steps, CLLocation *startPoint, CLLocation *endPoint, NSArray *directions) {
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
Annotation * startAnnotation = [[Annotation alloc]initWithCoordinate:startPoint.coordinate title:NSLocalizedString(@"YOUR_POSITION_KEY", @"Your position") annotationType:AnnotationTypeStart];
Annotation * endAnnotation = [[Annotation alloc]initWithCoordinate:endPoint.coordinate title:NSLocalizedString(@"AIRPORT_POSITION_KEY", @"Airport position") annotationType:AnnotationTypeEnd];
NSArray * annotationArray = [NSArray arrayWithObjects:startAnnotation, endAnnotation, nil];
weakSelf.routeSteps = steps;
weakSelf.routeDirections = directions;
weakSelf.duration = routeDuration;
weakSelf.distance = routeDistance;
CLLocationDegrees maxLat = -90.0f;
CLLocationDegrees maxLon = -180.0f;
CLLocationDegrees minLat = 90.0f;
CLLocationDegrees minLon = 180.0f;
for (int i = 0; i < weakSelf.routeSteps.count; i++) {
NSDictionary * stepDictCoordinate = [[weakSelf.routeSteps objectAtIndex: i]objectForKey:@"start_location"];
CLLocationCoordinate2D currentLocationCoordinate = CLLocationCoordinate2DMake([[stepDictCoordinate objectForKey:@"lat"]doubleValue], [[stepDictCoordinate objectForKey:@"lng"]doubleValue]);
if(currentLocationCoordinate.latitude > maxLat) {
maxLat = currentLocationCoordinate.latitude;
}
if(currentLocationCoordinate.latitude < minLat) {
minLat = currentLocationCoordinate.latitude;
}
if(currentLocationCoordinate.longitude > maxLon) {
maxLon = currentLocationCoordinate.longitude;
}
if(currentLocationCoordinate.longitude < minLon) {
minLon = currentLocationCoordinate.longitude;
}
}
MKCoordinateRegion region;
region.center.latitude = (maxLat + minLat) / 2;
region.center.longitude = (maxLon + minLon) / 2;
region.span.latitudeDelta = maxLat - minLat;
region.span.longitudeDelta = maxLon - minLon;
dispatch_async(dispatch_get_main_queue(), ^{
if ( error) {
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"Error", @"Error alert view title") message:NSLocalizedString(@"KEY_DIRECTIONS_ERROR", @"Alert error message for directions") delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
[_routesButton setEnabled:NO];
}
else{
[weakSelf.mapView addAnnotations:annotationArray];
[_routesButton setEnabled:YES];
if(routePolyline){
[weakSelf.mapView addOverlay:routePolyline];
}
else{
UIAlertView * alert = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"Error", @"Error alert view title") message:NSLocalizedString(@"KEY_DIRECTIONS_POLYLINE_ERROR", @"Polyline inconsistant") delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
}
//[weakSelf.mapView setRegion:region animated:YES];
[weakSelf setRegion:region];
}
});
}];}
如果我设置断点并询问视图控制器的 retainCount,我可以看到它会增加不同的时间,即使传递的视图控制器设置为弱。
任何帮助将不胜感激。
谢谢,
安德烈亚
/************更新********** */**
检查分配我可以看到,在块内,视图控制器被保留了很多次,通过一个名为-tryRetain 的方法直到递减,但它似乎错过了一个释放释放。
为了清楚起见,我必须指定将传递的块复制到类路由方向对象中。
我做了一个小样,你可以在这里下载:download project
【问题讨论】:
-
另外你不应该使用self类的实例变量(在块中),例如_routerButton。
-
OMG... 这里是注释两个 _routeButton 实例,一切都已正确释放,我认为它们只是被复制为单个实例。请把它写成我检查它的答案。非常感谢。
标签: ios block weak-references retain-cycle