2011-02-25 11 views
13

मैं पीडीएफ में पृष्ठों की पूर्वावलोकन छवियां बनाने की कोशिश कर रहा हूं लेकिन मुझे स्मृति की रिहाई के साथ कुछ समस्याएं हैं।UIGraphicsGetImageFromCurrentImageContext स्मृति रिसाव पूर्वावलोकन के साथ

मैं एक साधारण परीक्षण एल्गोरिथ्म ने लिखा है कि इस समस्या पर चक्र, 40 वीं यात्रा पास ऐप्लिकेशन क्रैश:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:@"myPdf.pdf"]; 
CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)pdfPath, kCFURLPOSIXPathStyle, NO); 
CGPDFDocumentRef myPdf = CGPDFDocumentCreateWithURL(url); 
CFRelease (url); 
CGPDFPageRef page = CGPDFDocumentGetPage(myPdf, 1); 

int i=0; 
while(i < 1000){ 

    UIGraphicsBeginImageContext(CGSizeMake(768,1024)); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetRGBFillColor(context, 1.0,1.0,1.0,1.0); 
    CGContextFillRect(context,CGRectMake(0, 0, 768, 1024)); 
    CGContextSaveGState(context); 
    CGContextTranslateCTM(context, 0.0, 1024); 
    CGContextScaleCTM(context, 1.0, -1.0); 
    CGContextDrawPDFPage(context, page); 
    CGContextRestoreGState(context); 

    // -------------------------- 
    // The problem is here (without this line the application doesn't crash) 
    UIImageView *backgroundImageView1 = [[UIImageView alloc] initWithImage:UIGraphicsGetImageFromCurrentImageContext()]; 
    // -------------------------- 

    UIGraphicsEndImageContext(); 
    [backgroundImageView1 release]; 

    NSLog(@"Loop: %d", i++); 
} 

CGPDFDocumentRelease(myPdf); 

उपर्युक्त लाइन, एक स्मृति रिसाव, तथापि उत्पन्न करने के लिए लगता है यंत्र स्मृति समस्याओं को नहीं दिखाता है;

क्या मैं इस तरह की गलती से बच सकता हूं? कोई मुझे किस तरह से समझा सकता है? क्या पीडीएफ के पूर्वावलोकन दिखाने के अन्य तरीके हैं?

अद्यतन

मुझे लगता है कि समस्या विधि UIGraphicsGetImageFromCurrentImageContext() लेकिन इस autorelease छवि के साथ बनाया UIImageView की रिहाई के द्वारा बनाई गई UIImage की रिहाई नहीं है।

मैं तीन चरणों में कोड की पंक्ति बांट दिया है:

UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIImageView *myImageView = [[UIImageView alloc] init]; 
[myImageView setImage: myImage]; // Memory Leak 

पहली और दूसरी लाइनों मेमोरी लीक का निर्माण नहीं करता तो मुझे लगता है कि विधि UIGraphicsGetImageFromCurrentImageContext समस्या नहीं है।

मैं भी लेकिन समस्या बनी रहती है इस प्रकार की कोशिश की:

UIImageView *myImageView = [[UIImageView alloc] initWithImage:myImage]; 

मुझे लगता है कि एक UIImageView कि autorelease संपत्ति के साथ एक UIImage शामिल की रिहाई में एक स्मृति रिसाव होती है।

मैंने अपनी ऑब्जेक्ट UIImageView को UIView को विरासत में लिखने की कोशिश की जैसा कि thread में बताया गया है।

यह समाधान काम करता है लेकिन यह बहुत ही सुरुचिपूर्ण नहीं है, यह एक कामकाज है, मैं स्मृति समस्या को हल करने के लिए UIImageView ऑब्जेक्ट का उपयोग करना पसंद करूंगा।

+0

स्मृति उपयोग की जांच के लिए आप किस यंत्र का उपयोग कर रहे हैं? मैं "आवंटन" और "गतिविधि मॉनिटर" देखता हूं, जिनमें से दोनों स्मृति उपयोग दिखा सकते हैं जो लीक उपकरण से चूक जाते हैं। इसके अलावा, यह कोड वैसे भी क्या करना चाहिए? आप 1000 छवि दृश्य बनाना चाहते हैं, लेकिन फिर उनका उपयोग किए बिना उनसे छुटकारा पाएं? –

+0

क्या आपको उत्तर मिला है? मुझे एक ही समस्या है: एस –

उत्तर

1

क्या यह कोड मुख्य धागे पर चल रहा है? UIGraphicsGetImageFromCurrentImageContext (link) का प्रलेखन कहता है कि इसे इस तरह से चलाना चाहिए।

+0

हां, मैंने ऐप्पल दस्तावेज पढ़ा है। मैं इस समारोह को मुख्य धागे पर कॉल करता हूं, वैसे भी आपकी प्रतिक्रिया के लिए धन्यवाद! – Alessandro

+8

'UIGraphicsGetImageFromCurrentImageContext' पर नवीनतम UIKit दस्तावेज़ीकरण से: 'आईओएस 4 और बाद में, आप इस फ़ंक्शन को अपने ऐप के किसी भी थ्रेड से कॉल कर सकते हैं। – chown

23

समस्या यह है:

UIGraphicsGetImageFromCurrentImageContext() 

रिटर्न एक autoreleased UIImage। ऑटोरेलीज पूल इस छवि पर तब तक रहता है जब तक आपका कोड रनलोप पर नियंत्रण नहीं देता है, जिसे आप लंबे समय तक नहीं करते हैं। इस समस्या को हल करने के लिए, आपको अपने while लूप के प्रत्येक पुनरावृत्ति (या प्रत्येक कुछ पुनरावृत्तियों) पर एक ताजा ऑटोरेलीज पूल बनाना और निकालना होगा।

+2

मैंने प्रत्येक पुनरावृत्ति पर NSAutoreleasePool बनाने और रिलीज़ करने का प्रयास किया लेकिन स्मृति समस्या बनी रहती है। वैसे भी आपकी प्रतिक्रिया के लिए धन्यवाद! – Alessandro

+0

क्या आपको कोई समाधान मिला? – spd

+0

मेरे लिए काम किया। पारितोषिक के लिए धन्यवाद! – pstoppani

-1

दुर्घटना की अपनी लाइन आप इसका अनुसरण

लूप से बाहर

rendered_image = UIGraphicsGetImageFromCurrentImageContext() एक UIImage प्राप्त की तरह अद्यतन कर सकते हैं;

9

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैं कुछ घंटे के लिए दीवार पर अपने सिर को टक्कर लगी हूं। मेरे ऐप में बार-बार

UIImage *image = UIGraphicsGetImageFromCurrentImageContext() 

एक लूप में छवि को कॉल करने के बावजूद स्मृति को पकड़ता है; यह सुनिश्चित नहीं है कि ऐप फ्रीिंग से पहले मेमोरी को कितनी देर तक रखेगा, लेकिन मेरे ऐप को स्मृति चेतावनी मिलने के बाद यह निश्चित रूप से काफी लंबा है।

मैं अंततः कोड को लपेटकर इसे हल करने में कामयाब रहा हूं जो UautraphicsGetImageFromCurrentImageContext() से @autoreleasepool में छवि को कॉल/उपयोग करता है। तो मेरे पास है:

@autoreleasepool { 
    UIImage *image = [self imageWithView:_outputImageView]; //create the image 
    [movie addImage:image frameNum:i fps:kFramesPerSec]; //use the image as a frame in movie 
    image = nil; 
} 

आशा है कि किसी की मदद कर सकता है।

+0

यह मेरे लिए था! धन्यवाद :) – davvilla