2012-11-13 282 views
0


我有一個塊和弱引用的問題,我在ARC下。我建立了一個類,它是一個免費的項目,它是一個簡單的谷歌方向API包裝,你可以在這裏下載它:link to the project
Im'm在視圖控制器內使用它的問題是,使用它後視圖控制器不釋放。我想這是這個對象的問題,因爲如果我將它註釋掉或設置爲零,一切正常。我不能明白哪裏是保留週期,當然我設置爲弱的自我,這裏是我用它的視圖控制器的方法:塊和保留週期不能捕捉它

- (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我可以看到,即使視圖控制器通過設置爲弱,它也會增加不同的時間。 任何幫助將非常感激。
謝謝,
安德烈

/* ** * ** * ** * **UPDATE* ** * ** * ** * */**
檢查分配我可以看到,在塊內視圖控制器保留了很多次通過一個叫做-tryRetain的方法,直到遞減,但它似乎錯過了釋放一次釋放。 爲了清晰起見,我必須指定傳遞的塊被複制到類路徑方向對象中。 我做了一個小樣本,你可以在這裏下載:download project

+0

還你不應該使用實例變量(塊)自我類,_routerButton例如。 – NeverBe

+0

OMG ...在這裏它正在評論兩個_routeButton實例,一切都正確處理,我認爲它們只是作爲單個實例複製。請把它寫爲答覆,我檢查它。非常感謝。 – Andrea

回答

-1

你不應該使用自我類,_routerButton的實例變量(塊)你的情況

+0

謝謝隊友!!!! – Andrea

+1

你能提供**你爲什麼不應該? – WDUK

+0

@WDUK http://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/Blocks/Articles/bxVariables.html – NeverBe

0

你可以使用儀器來確定什麼是保留和釋放你的對象,並找出不平衡發生的地方。這可以通過在構建和運行項目時選擇配置文件來完成,並且您將啓動儀器。

進入後,您可以選擇泄漏來確定泄漏發生的位置。 enter image description here

幾個導遊,你可以用它來獲得儀器的抓地力:

+0

非常感謝WDUK,它不會改變。 R.C.是相同的。在進入對象之前,它的RC爲1,當它出現時爲6. – Andrea

+0

您是否嘗試記錄儀器中保留的內容?你可以看到它被保留和釋放的地方,然後找到不平衡發生的地方?將更新答案以反映這種方法。 – WDUK

+0

當然,這是令人難以置信的..在對象的RC歷史中,我可以清楚地看到它進入塊內並獲得很多增量,奇怪的是我手動獲取的引用計數與泄漏中顯示的引用計數不同 – Andrea

1

對象的絕對保留計數是毫無意義的; www.whentouseretaincount.com(底部有一些鏈接描述技術細節)。

泄漏儀器不太可能提供幫助。它可能,但也許不是。但是,分配工具是你的朋友。打開「記錄引用計數」和「僅跟蹤活動分配」。在樂器中運行你的應用程序,然後尋找應該消失的物體,但不是。點擊任何一個將顯示該對象的保留/釋放事件,這將回答額外保留來自哪裏的問題。

更可能的是,鑑於這是一個視圖對象,這是因爲它仍然在視圖層次結構中,但被埋在其他不透明視圖的後面。它也可以作爲定時器的目標或緩存中的目標,可能是「返回」式導航緩存。

+0

你好,謝謝你的回答。我已經使用分配檢查了項目,並且似乎視圖控制器保留了很多時間進入方法,我可以清楚地看到堆棧調用一個方法-tryRetain加上其他與事件相關的方法。我已經用示例項目更新了答案,以檢查保留視圖控制器的其他對象。正如你所看到的,你用視圖控制器和地圖查看路由,當你彈出它時,即使在導航控制器堆棧中沒有引用,它也不會被釋放。 – Andrea