2013-05-07 94 views
9

我有一個自定義UIView調用ActivityDetailView,我實例化,然後添加到父視圖控制器內的滾動視圖。分配此自定義視圖時,每增加一次內存就會佔用大約1mb的時間,並且Instruments顯示內存永遠不會被釋放,即使視圖和父視圖控制器各自都調用了它們的dealloc方法。我收到內存警告,應用程序最終被殺死,所以我顯然做錯了什麼。內存不被釋放MKMapView w/ARC

更新W繞地圖視圖是事業/信息,但我需要一個修復

在自定義ActivityDetailView筆尖文件,則存在被放大和周圍的用戶的位置爲中心的地圖視圖。當我從筆尖移除該地圖視圖時,它不會在屏幕上繪圖,內存分配問題就會消失。不過,我顯然需要地圖視圖。爲什麼當地圖視圖超出範圍時地圖視圖的數據不會被釋放?

當視圖顯示時,只有1 ActivityDetailView和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"); 
} 

在父視圖控制器:

@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 screenshot

我沒有任何東西g暫時緩存。該視圖基本上是一個滾動視圖,其中包含一個mapview,一些標籤和一些表視圖。表視圖沒有填充任何東西,我不在視圖內加載任何圖像,除了滾動視圖的背景圖像以外,但是當視圖發生時,它應該被釋放。

+1

不知道這是否是問題(也不應該是)。但是這兩行代碼是錯誤的detailView = nil; [detailView removeFromSuperview] ;.您應該調用removeFromSuperView,然後將其設置爲nil。 – Cosmin 2013-05-07 13:23:17

+0

@Cosmin我認爲沒關係,如果它仍然被添加到另一個視圖中,它不會達到dealloc ...我猜我們的OP只是在嘗試一些東西,並將它留下。 – 2013-05-07 13:27:40

+0

@Cosmin As Grady說,我只是在嘗試任何事情,看看它是否有所作爲,但事實並非如此。 – ZeNewb 2013-05-07 13:31:30

回答

22

事實證明,iOS 6和MKMapView存在已知的錯誤,無法正確釋放其內存。不幸的是,除了試圖強制地圖視圖清除緩存,這對釋放內存沒有太大的影響。

奇怪的是,即使應用程序收到內存警告,地圖視圖緩存仍未正確清除。最終,該應用程序變得不穩定,並被操作系統殺死。

最近蘋果一直在測試中很sl sl。這是我遇到的MKMapView的第二個錯誤(另一個是早期調用mapViewDidFinishLoadingMap:),如果他們剛剛進行了一些性能和完整性測試,那麼這兩個錯誤都非常明顯。

下面是一些代碼,可能會有幫助:

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 

    // This is for a bug in MKMapView for iOS6 
    [self purgeMapMemory]; 
} 

// This is for a bug in MKMapView for iOS6 
// Try to purge some of the memory being allocated by the map 
- (void)purgeMapMemory 
{ 
    // Switching map types causes cache purging, so switch to a different map type 
    detailView.mapView.mapType = MKMapTypeStandard; 
    [detailView.mapView removeFromSuperview]; 
    detailView.mapView = nil; 
} 

你可以做的另一件事是使用您的整個應用程序的MKMapView的一個實例,應該有助於減少每次多少內存分配的觀點因爲地圖視圖已經被分配了。

+0

偉大的建議,重新:使用MKMapView的一個實例,而不是每次alloc/dealloc'ing新的。我遇到了類似的問題......我們知道這個錯誤是否已從iOS 9+中解決? – 2016-08-26 14:49:54

+1

@ AdamW.Dennis我幾年前還沒有在Apple地圖上工作過,所以您可能想要查看OpenRadar或Apple開發論壇以查看是否可以找到更多信息,例如https://openradar.appspot.com/search?query=mkmapview+memory – iwasrobbed 2016-08-26 15:17:21

0

這不是從您的筆尖文件創建自定義視圖的最佳方式。我建議你做的是將你從.nib文件作爲subview的視圖添加到self中。代碼應該看起來像這樣。

-(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 addSubview:xibView]; // This is where I have changed your code 
    } 
    return self; 
} 
+0

不幸的是,這對內存分配沒有任何影響。 – ZeNewb 2013-05-07 13:35:05

+0

但你應該考慮他在說什麼,總是會受到幫助表示讚賞 – 2013-09-25 22:40:39

0

您可能會遇到緩存問題。

如果您使用的圖像很多,也許一個好的選擇是從xib中刪除這些圖像,並使用代碼添加它。或者,如果您使用[UIImage imageNamed:@""]

加載圖像,但使用這樣的事情:

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

爲了更好的幫助,我需要知道如何開始你的表,還有其他功能。

+0

我目前沒有任何東西需要緩存。該視圖基本上是一個scrollview,裏面有一個mapview和一些標籤。表視圖沒有填充任何東西,我不在視圖內加載任何圖像,除了滾動視圖的背景圖像以外,但是當視圖發生時,它應該被釋放。 – ZeNewb 2013-05-07 15:04:31

+0

Nop,您在視圖中添加的圖像,使用imagenamed或從xib緩存,有時會導致應用程序崩潰。 – ggrana 2013-05-07 15:05:59

+0

背景圖像被添加到筆尖中,並且與應用程序的其餘部分使用的背景圖像相同,所以我不認爲這是問題。沒有其他觀點有分配問題,只有這個。 – ZeNewb 2013-05-07 15:07:14