tldr: ImagedNamed ठीक है। यह मेमोरी को अच्छी तरह से हैंडल करता है। इसका उपयोग करें और चिंता करना बंद करें।
नवंबर 2012 को संपादित करें : ध्यान दें कि यह प्रश्न iOS 2.0 से आता है! तब से छवि आवश्यकताएँ और हैंडलिंग बहुत आगे बढ़ गई हैं। रेटिना छवियों को बड़ा बनाता है और उन्हें थोड़ा और अधिक जटिल लोड करता है। IPad और रेटिना छवियों के समर्थन में निर्मित होने के साथ, आपको निश्चित रूप से अपने कोड में ImageNamed का उपयोग करना चाहिए। अब, पोस्टर की खातिर:
बहन धागा एप्पल देव मंच पर कुछ बेहतर यातायात प्राप्त किया। विशेष रूप से Rincewind ने कुछ प्राधिकरण जोड़े।
IPhone OS 2 में ऐसे मुद्दे हैं जहाँ छवि का नाम दिया गया है: मेमोरी चेतावनी के बाद भी कैश क्लियर नहीं किया जाएगा। एक ही समय में + इमेजनाम: कैश के लिए नहीं बल्कि सुविधा के लिए बहुत अधिक उपयोग किया है, जिसने शायद समस्या को और अधिक बढ़ा दिया है।
चेतावनी देते हुए
गति के मोर्चे पर, एक सामान्य गलतफहमी है कि क्या चल रहा है। सबसे बड़ी बात यह है कि + इमेजनाम: स्रोत फ़ाइल से छवि डेटा को डीकोड करता है, जो लगभग हमेशा डेटा आकार को बढ़ाता है (उदाहरण के लिए, एक स्क्रीन आकार पीएनजी फ़ाइल संकुचित होने पर कुछ दर्जन केबी का उपभोग कर सकता है, लेकिन आधे से अधिक एमबी का उपभोग करता है विघटित - चौड़ाई * ऊंचाई * 4)। इसके विपरीत + imageWithContentsOfFile: छवि डेटा की जरूरत है कि छवि हर बार decompress होगा। जैसा कि आप कल्पना कर सकते हैं, यदि आपको केवल एक बार छवि डेटा की आवश्यकता है, तो आपने यहां कुछ भी नहीं जीता है, केवल छवि के कैश्ड संस्करण को छोड़कर चारों ओर लटके हुए हैं, और आपकी आवश्यकता से अधिक समय तक रहने की संभावना है। हालाँकि, यदि आपके पास एक बड़ी छवि है जिसे आपको अक्सर फिर से तैयार करने की आवश्यकता होती है, तो विकल्प हैं, हालांकि मैं जो मुख्य रूप से सुझाऊंगा वह बड़ी छवि को फिर से बनाने से बचने के लिए है :)।
कैश के सामान्य व्यवहार के संबंध में, यह फ़ाइल नाम के आधार पर कैश करता है (इसलिए दो उदाहरणों + छविनाम: एक ही नाम के साथ एक ही कैश्ड डेटा के संदर्भ में परिणाम होना चाहिए) और कैश गतिशील रूप से बढ़ेगा क्योंकि आप अधिक छवियों का अनुरोध करते हैं + imageNamed :. IPhone OS 2.xa बग पर मेमोरी चेतावनी मिलने पर कैश को सिकुड़ने से रोकता है।
तथा
मेरी समझ यह है कि + छवि नाम: कैश को iPhone OS 3.0 पर मेमोरी चेतावनी का सम्मान करना चाहिए। मौका मिलने पर टेस्ट करें और बग्स को रिपोर्ट करें कि क्या आपको पता है कि ऐसा नहीं है।
इसलिए यह अब आपके पास है। imageNamed: अपनी खिड़कियों को तोड़ना या अपने बच्चों की हत्या नहीं करेगा। यह बहुत आसान है, लेकिन यह एक अनुकूलन उपकरण है। अफसोस की बात है कि यह बुरी तरह से नामांकित है और कोई ऐसा समतुल्य नहीं है जिसका उपयोग करना उतना ही आसान है - इसलिए लोग इसे अधिक उपयोग करते हैं और परेशान हो जाते हैं जब यह बस अपना काम करता है
मैंने इसे ठीक करने के लिए UIImage में एक श्रेणी जोड़ी:
// header omitted
// Before you waste time editing this, please remember that a semi colon at the end of a method definition is valid and a matter of style.
+ (UIImage*)imageFromMainBundleFile:(NSString*)aFileName; {
NSString* bundlePath = [[NSBundle mainBundle] bundlePath];
return [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@", bundlePath,aFileName]];
}
रेनविंड ने आपके स्वयं के अनुकूलित संस्करण के निर्माण के लिए कुछ उदाहरण कोड भी शामिल किए हैं। मैं यह नहीं देख सकता कि यह मुख्य मूल्य के लायक है लेकिन यहाँ यह पूर्णता के लिए है।
CGImageRef originalImage = uiImage.CGImage;
CFDataRef imageData = CGDataProviderCopyData(
CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
CGImageGetBitsPerComponent(originalImage),
CGImageGetBitsPerPixel(originalImage),
CGImageGetBytesPerRow(originalImage),
CGImageGetColorSpace(originalImage),
CGImageGetBitmapInfo(originalImage),
imageDataProvider,
CGImageGetDecode(originalImage),
CGImageGetShouldInterpolate(originalImage),
CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);
UIImage *decompressedImage = [UIImage imageWithCGImage:image];
CGImageRelease(image);
इस कोड के साथ व्यापार यह है कि डिकोड की गई छवि अधिक मेमोरी का उपयोग करती है लेकिन रेंडरिंग तेज है।