0


ブロックと弱参照に問題があります。ARCの下にいます。私はクラスを作成しました。これは無料のプロジェクトで、Google Directions APIの一種の簡単なラッパーです。ここからダウンロードできます。プロジェクトへのリンク
ビューコントローラー内で使用しています。問題は、使用後のビューコントローラーが割り当てが解除されていません。コメントアウトするか、nilに設定すると、すべてが正しく機能するため、これはこのオブジェクトの問題だと思います。保持サイクルがどこにあるのか理解できません。もちろん、弱い自己に設定しました。これを使用するViewControllerのメソッドは次のとおりです。

- (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];
        }
    });
}];}

ブレークポイントを設定してViewControllerのretainCountを要求すると、渡されたView Controllerがweakに設定されている場合でも、異なる時間に増分されることがわかります。どんな助けでも本当にありがたいです。
ありがとう、
アンドレア

/ * ** * ** * ** * ** UPDATE * ** * ** * ** * * / **
割り当てを確認するブロック内で、ビューコントローラが何度も保持されていることがわかります。 tillと呼ばれるメソッド-tryRetainはデクリメントされますが、割り当て解除のために1つのリリースを見逃しているようです。念のため、渡されたブロックがクラスルート方向オブジェクトにコピーされることを指定する必要があります。ここからダウンロードできる小さなサンプルを作成しました:プロジェクトのダウンロード

4

3 に答える 3

1

オブジェクトの絶対保持数は無意味です。www.whentouseretaincount.com(技術的な詳細を説明するいくつかのリンクが下部にあります)。

Leaks機器が役立つ可能性は低いです。そうかもしれませんが、そうではないかもしれません。ただし、AllocationsInstrumentはあなたの友達です。「参照カウントの記録」と「アクティブな割り当てのみを追跡」をオンにします。Instrumentsでアプリを実行し、消えるはずのオブジェクトを探しますが、消えないオブジェクトを探します。いずれかをクリックすると、そのオブジェクトの保持/解放イベントが表示され、追加の保持がどこから来ているのかという質問に答えます。

ほとんどの場合、これはビューオブジェクトであるため、ビュー階層内にあるが、他の不透明なビューの背後に埋め込まれているためです。また、タイマーのターゲットとして、またはキャッシュ、場合によっては「戻る」スタイルのナビゲーションキャッシュに保持されることもあります。

于 2012-11-13T17:42:13.333 に答える
0

Instrumentsを使用して、オブジェクトを保持および解放しているものを判別し、不均衡が発生している場所を特定できます。これは、プロジェクトをビルドして実行するときに[プロファイル]を選択することで実行でき、計測器を起動します。

入ったら、リークを選択して、リークが発生している場所を特定できます。 ここに画像の説明を入力してください

インストゥルメントを把握するために使用できるガイドは次のとおりです。

于 2012-11-13T14:12:42.550 に答える
-1

自己クラスのインスタンス変数(ブロック単位)、この場合は_routerButtonを使用しないでください

于 2012-11-14T10:46:52.720 に答える