2013-05-07 7 views
9

के लिए मेमोरी जारी नहीं की जा रही है मेरे पास UIView है जिसे ActivityDetailView कहा जाता है जिसे मैं तत्काल करता हूं और फिर मूल दृश्य नियंत्रक के भीतर स्क्रॉलव्यू में जोड़ता हूं। जब यह कस्टम व्यू आवंटित किया जाता है, तो यह अतिरिक्त मेमोरी के हर बार लगभग 1 एमबी लेता है और इंस्ट्रूमेंट्स दिखा रहा है कि स्मृति को कभी भी जारी नहीं किया जा रहा है, भले ही दृश्य और अभिभावक दृश्य नियंत्रक प्रत्येक के पास dealloc विधियों को बुलाया जा सके। मुझे स्मृति चेतावनियां मिल रही हैं और ऐप अंततः मारे जा रहा है इसलिए मैं कुछ गलत कर रहा हूं।MKMapView w/ARC

डब्ल्यू के बारे में मानचित्र दृश्य कारण किया जा रहा/जानकारी अपडेट किया गया है, लेकिन मैं एक फिक्स

जरूरत कस्टम 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

मेरे पास कोई नहीं है इस समय कैश करने के लिए जी। दृश्य मूल रूप से इसके अंदर एक नक्शादृश्य और कुछ लेबल और कुछ तालिका दृश्यों के साथ एक स्क्रॉलव्यू है। तालिका दृश्य किसी भी चीज़ के साथ पॉप्युलेट नहीं होते हैं और मैं स्क्रॉलव्यू के लिए पृष्ठभूमि छवि के अलावा किसी भी छवि को लोड नहीं कर रहा हूं, लेकिन जब दृश्य करता है तो इसे रिलीज़ किया जाना चाहिए।

+1

सुनिश्चित नहीं है कि यह समस्या है (और यह नहीं होना चाहिए)। लेकिन कोड की ये दो पंक्तियां गलत विवरण हैं व्यू = शून्य; [विवरण देखें हटाएं FromSuperview]; आपको removeFromSuperView को कॉल करना चाहिए और उसके बाद इसे शून्य पर सेट करना चाहिए। – Cosmin

+0

@Cosmin अच्छी तरह से मुझे लगता है कि इससे कोई फर्क नहीं पड़ता है, अगर यह अभी भी किसी अन्य दृश्य में जोड़ा गया है तो यह डेलोक नहीं होगा ... मुझे लगता है कि हमारा ओपी बस सामान की कोशिश कर रहा था, और इसे छोड़ दिया। –

+0

@Cosmin As Grady ने कहा, मैं बस उस बिंदु पर कुछ भी कोशिश कर रहा था यह देखने के लिए कि क्या इससे कोई फर्क पड़ता है, लेकिन ऐसा नहीं हुआ। – ZeNewb

उत्तर

22

जैसा कि यह पता चला है, आईओएस 6 और MKMapView के साथ एक ज्ञात बग है जो इसकी स्मृति को सही ढंग से जारी नहीं कर रहा है।दुर्भाग्य से नक्शा दृश्य को अपने कैश को शुद्ध करने के लिए मजबूर करने की कोशिश करने के अलावा कोई वास्तविक फिक्स नहीं है, जिसमें स्मृति जारी करने पर बहुत अधिक असर नहीं पड़ता है।

अजीब बात यह है कि जब भी ऐप मेमोरी चेतावनियां प्राप्त कर रहा है, तब भी नक्शा व्यू कैश को ठीक से शुद्ध नहीं किया जा रहा है। आखिरकार, ऐप अस्थिर हो जाता है और ओएस द्वारा मारा जाता है।

ऐप्पल हाल ही में अपने परीक्षण के साथ बहुत मैला हो रहा है। यह 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

ग्रेट सुझाव, पुन: एमके मैप व्यू के एक उदाहरण का उपयोग करके, प्रत्येक बार नए/आवंटित करने के बजाए। मुझे समान समस्याएं आ रही हैं ... क्या हमें पता है कि यह बग आईओएस 9 + के रूप में तय किया गया है? –

+1

@ AdamW.Dennis मैंने कुछ वर्षों में डब्ल्यू/ऐप्पल मैप्स का काम नहीं किया है, इसलिए आप ओपनराडर या ऐप्पल देव मंचों पर जांच कर सकते हैं ताकि आप यह जान सकें कि क्या आप अधिक जानकारी प्राप्त कर सकते हैं, उदा। https://openradar.appspot.com/search?query=mkmapview+memory – iwasrobbed

0

यह आपकी निब फ़ाइल से कस्टम दृश्य बनाने का सबसे अच्छा तरीका नहीं है। मैं जो सुझाव देता हूं वह है कि आप एनएनआई फाइल से स्वयं को एक सबव्यूव के रूप में लेते हुए दृश्य जोड़ना चाहते हैं। कोड इस तरह कुछ दिखना चाहिए।

-(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

+0

लेकिन आपको यह विचार करना चाहिए कि वह क्या कह रहा है, हमेशा मदद की जाती है –

0

आपको शायद कैश के साथ समस्या का सामना करना पड़ रहा है।

यदि आप बहुत सारी छवियों का उपयोग कर रहे हैं तो शायद इस छवि को xib से निकालने और कोड का उपयोग करके इसे जोड़ने का एक अच्छा विकल्प है। या यदि आप [UIImage imageNamed:@""]

का उपयोग कर छवियों को लोड लेकिन ऐसा ही कुछ का उपयोग करें:

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

बेहतर मदद करने के लिए मुझे पता है कि कैसे आप अपने टेबल और भी दूसरों सुविधाओं शुरू की जरूरत है।

+0

मेरे पास इस समय कैश करने के लिए कुछ भी नहीं है। दृश्य मूल रूप से इसके अंदर एक नक्शादृश्य और कुछ लेबल के साथ एक स्क्रॉलव्यू है। तालिका दृश्य किसी भी चीज़ के साथ पॉप्युलेट नहीं होते हैं और मैं स्क्रॉलव्यू के लिए पृष्ठभूमि छवि के अलावा किसी भी छवि को लोड नहीं कर रहा हूं, लेकिन जब दृश्य करता है तो इसे रिलीज़ किया जाना चाहिए। – ZeNewb

+0

नहीं, छवि जिसे आप अपने दृश्य में जोड़ते हैं, कल्पना या xib से उपयोग करके कैश किए जाते हैं और कभी-कभी यह ऐप को क्रैश कर सकता है। – ggrana

+0

पृष्ठभूमि छवि को निब में जोड़ा गया है और यह वही पृष्ठभूमि छवि है जो पूरे ऐप में उपयोग की जाती है, इसलिए मुझे नहीं लगता कि यह समस्या है। किसी अन्य विचार में आवंटन के मुद्दों में से कोई भी नहीं है, केवल यह ही करता है। – ZeNewb