9

インスタンス化してから、親ビューコントローラー内のスクロールビューに追加するカスタムUIView呼び出しがあります。ActivityDetailViewこのカスタム ビューが割り当てられると、メモリが追加されるたびに約 1MB が消費され、Instruments は、ビューと親ビュー コントローラのdeallocメソッドがそれぞれ呼び出されているにもかかわらず、メモリが決して解放されていないことを示しています。メモリの警告が表示され、アプリが最終的に強制終了されるため、明らかに何か間違ったことをしています。

マップ ビューが原因であるという情報で更新されましたが、修正が必要です

カスタムActivityDetailViewnib ファイル内には、ズームされ、ユーザーの場所を中心に配置されたマップ ビューがあります。このマップ ビューを nib から削除して画面に描画しないようにすると、メモリ割り当ての問題は解消されました。ただし、明らかにマップビューが必要です。マップ ビューが範囲外になると、マップ ビューのデータが解放されないのはなぜですか?

ビューが表示されているとき、生きているのは 1ActivityDetailViewと 1だけです。ActivityDetailViewControllerスタックからビューを取り出すとすぐに、それらはもはや生きていません。インストルメントを介して示されているように、オブジェクトが強制終了されているにもかかわらず、メモリがどのように増加し続けるのか意味がありません。親ビューの割り当てが解除されている場合、マップ ビュー データの割り当てが解除されないのはなぜですか?

私は何を間違っていますか、または何を確認する必要がありますか?

カスタムビューは次のとおりです。

@interface ActivityDetailView ()
{
    CLLocation *location;
    __weak id parentViewController;
    int scrollViewX;

    ImageUtility *imageUtility;
}
@end

@implementation ActivityDetailView

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        NSArray *xibViews = [[NSBundle mainBundle] loadNibNamed:@"ActivityDetailView" owner:nil options:nil];
        if ([xibViews count] < 1) return nil;
        ActivityDetailView * xibView = [xibViews objectAtIndex:0];
        [xibView setFrame:frame];
        self = xibView;
    }
    return self;
}

- (id)initWithLocation:(CLLocation *)loc parentController:(id)parent
{
    self = [self initWithFrame:CGRectMake(0, 0, 320, 1000)];
    if (self)
    {
        imageUtility = [ImageUtility sharedManager];

        location = loc;
        parentViewController = parent;
        scrollViewX = 0;

        [self centerMapForActivityLocation];
        [self addPhotoButtonWithImageNamed:@"addActivityPhoto.png" target:parentViewController selector:@selector(addPhotoToActivity:)];
    }
    return self;
}

- (void)dealloc
{
    NSLog(@"ActivityDetailView was dealloced");
}

親View Controllerで:

@interface ActivityDetailViewController ()
{
    ActivityDetailView *detailView;
}
@end

@implementation ActivityDetailViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Some code left out for clarity

    [self setupView];
}

- (void)didReceiveMemoryWarning
{
    NSLog(@"Purging image cache");
    [[ImageUtility sharedManager] purgeCache];
}

- (void)dealloc
{
    // These essentially do nothing to help the problem
    detailView.mapView = nil;
    [detailView removeFromSuperview];
    detailView = nil;
    self.scrollView = nil;

    NSLog(@"ActivityDetailViewController was dealloced");
}

- (void)setupView
{    
    // Add the activity detail view to the scroll view
    detailView = [[ActivityDetailView alloc] initWithLocation:self.activityLocation parentController:self];
    [self.scrollView addSubview:detailView];
    self.scrollView.contentSize = detailView.frame.size;

    // Setup the map view
    detailView.mapView.delegate = self;
    MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
    annotation.coordinate = self.activityLocation.coordinate;
    [detailView.mapView addAnnotation:annotation];
    if (self.activity.mapImageName) {
        detailView.mapView.scrollEnabled = YES;
        detailView.mapView.zoomEnabled = YES;
    } else {
        detailView.mapView.scrollEnabled = NO;
        detailView.mapView.zoomEnabled = NO;
    }

    // Add the weather area to the view
    dayView = [[DailyButtonView alloc] initWithFrame:CGRectMake(0, -17, 60, 70)];
    dayView.hidden = YES;
    [detailView.weatherView addSubview:dayView];
}

これは、メモリの大部分がペン先の読み込みによるものであることを示すInstrumentsの画像です。

楽器のスクリーンショット

現在、キャッシュするものはありません。ビューは基本的に、その中にマップビューがあり、いくつかのラベルといくつかのテーブルビューがあるスクロールビューです。テーブルビューには何も入力されておらず、スクロールビューの背景画像以外の画像をビュー内にロードしていませんが、ビューが解放されたときに解放されるはずです。

4

3 に答える 3

0

キャッシュに問題がある可能性があります。

多くの画像を使用している場合は、この画像を xib から削除し、コードを使用して追加することをお勧めします。または、を使用して画像をロードする場合 [UIImage imageNamed:@""]

しかし、そのようなものを使用してください:

NSData* dataImg = [NSData dataWithContentsOfFile:@"yourfile.png"];
UIImage* img = [UIImage imageWithData:dataImg];

より良い手助けをするために、テーブルと他の機能をどのように開始するかを知る必要があります.

于 2013-05-07T15:02:08.333 に答える