2012-04-19 42 views
8

मैंने आईओएस पर छवि प्रदर्शन का परीक्षण करने के लिए एक ऐप लिखा है। मैंने 3 अलग-अलग विचारों की कोशिश की है, सभी एक ही बड़े पीएनजी प्रदर्शित करते हैं। पहला ऐसा दृश्य है जो CGContextDrawImage() का उपयोग करता है। दूसरा सेट self.layer.content। तीसरा एक सादा UIImageView है।UIImageView या तो सीजी या कैलियर से बहुत तेज प्रदर्शित करता है। किसी को पता है क्यों?

उपयोग की गई छवि का उपयोग - [UIImage initWithContentsOfData:] और व्यू कंट्रोलर में कैश किया गया है। प्रत्येक परीक्षण बार-बार एक दृश्य को आवंटित करता है, इसे दृश्य पदानुक्रम में जोड़ता है और फिर इसे हटा देता है और इसे रिलीज़ करता है। लोडव्यू की शुरुआत से समय लिया जाता है ताकि डीडएपियर को देखा जा सके और एफपीएस के रूप में दिया जा सके (प्रभावी रूप से प्रति सेकंड ड्रॉ देखें)।

CGContext: 11 fps 
CALayer:  10 fps 
UIImageView: 430 fps (!) 

Am मैं hallucinating:

यहाँ एक 912 x 634 बगैर माप छवि का उपयोग कर 5.1 चल रहा एक iPad 1 से परिणाम कर रहे हैं? ऐसा लगता है कि UIImageView उस तेजी से आकर्षित कर सकता है, लेकिन मैं वास्तव में छवियों झिलमिलाहट देख सकते हैं। मैंने संभावित कैशिंग को हराने के लिए दो समान विचारों के बीच स्वैपिंग करने की कोशिश की, लेकिन फ्रेम दर भी अधिक थी।

मैंने हमेशा यह माना था कि UIImageView केवल एक रैपर था - [CALayer setContent]। हालांकि, UIImageView प्रोफाइलिंग किसी भी ड्राइंग विधि में लगभग कोई समय बिताता है जिसे मैं पहचान सकता हूं।

मुझे यह समझना अच्छा लगेगा कि क्या हो रहा है। कोई भी सहायता सराहनीय होगी।

+1

कृपया प्रत्येक प्रश्न में आपके द्वारा दिए गए कोड को शामिल करने के लिए अपना प्रश्न संपादित करें, या इसके लिए एक लिंक शामिल करें। –

+0

कोड हमारे मालिकाना गेम कोड का परीक्षण करने के लिए उपयोग किए जाने वाले एक बड़े ऐप का हिस्सा है। प्रासंगिक बिट्स को खींचने में कुछ घंटे लगेंगे। इस बीच, मुझे उपर्युक्त विवरण से आप जो भी विशिष्ट विवरण खो रहे हैं, उसे भरने में मुझे खुशी होगी। –

+0

"लोडव्यू की शुरुआत से समय निकाल दिया जाता है ताकि डीडएपियर देखने के लिए" - यह थोड़ा बोगस लगता है, क्योंकि वास्तव में स्क्रीन पर दिखाई देने से पहले 'viewDidAppear' को कॉल किया जा सकता है।यदि आप स्क्रीन को अपडेट करने के लिए मजबूर नहीं कर रहे हैं, तो आप वास्तव में कुछ भी उपयोगी नहीं कर रहे हैं; आप कई UIImageViews बना और नष्ट कर सकते हैं लेकिन केवल एक ही वास्तव में खींचा जाता है। मुझे आश्चर्य है कि क्या UIImageView '-layoutSubviews' में अपनी परत की सामग्री ऑन-डिमांड सेट कर रहा है - यह निश्चित रूप से मैं यह कैसे करूँगा, यह सुनिश्चित करने के लिए कि मैंने प्रति स्क्रीन अपडेट केवल एक बार परत को छुआ था। –

उत्तर

1

मेरा विचार यहां है।

जब आप किसी दृश्य को जोड़ने, हटाने या संशोधित करके, UIView पदानुक्रम को संशोधित करते हैं, तो कोई वास्तविक चित्र अभी तक नहीं किया जाता है। इसके बजाय दृश्य को 'setNeedsDisplay' के साथ चिह्नित किया गया है, और अगली बार रनलोप आकर्षित करने के लिए स्वतंत्र है।

वास्तव में, (मैं केवल अनुमान लगा सकते हैं) अपने परीक्षण कोड कुछ इस तरह दिखता है:

for (int i=0; i<10000; i++) { 
    UIImageView* imageView = [[UIImageView alloc] initWithFrame:frame]; 
    [mainView addSubview: imageView]; 
    [imageView setImage: image]; 
    [mainView removeSubview: imageView]; 
} 

से runloop जब तक पाश के लिए इस प्रक्रिया के बाद अवरुद्ध है। दृश्य पदानुक्रम केवल एक बार खींचा जाता है, मापा प्रदर्शन ऑब्जेक्ट आवंटित करने और प्रारंभ करने का होता है।

दूसरी ओर, CGContextDrawImage() तुरंत आकर्षित करने के लिए स्वतंत्र है, मुझे लगता है।

+1

हाँ, मैं निश्चित रूप से ऐसा नहीं कर रहा हूं। हालांकि, यह एक उचित supposition है। मेरा परीक्षण अनुक्रम प्रत्येक चरण के बाद रन लूप पर वापस आ जाता है। हम फ़ंज़ियो में यहां एक बड़ी रिलीज के बीच में सही हैं, लेकिन मैं कल की शुरुआत में जिथब पर प्रोजेक्ट की एक प्रति प्राप्त करने का प्रयास करूंगा। सहायता के लिए धन्यवाद। –

0

UIImageView छवियों को प्रस्तुत करने का एक अलग तरीका उपयोग करता है जो अधिक कुशल है। आप WWDC 2011 से इस सत्र वीडियो बताता है कि कैसे प्रतिपादन प्रक्रिया काम करता है पर एक नजर है चाहिए: https://developer.apple.com/videos/wwdc/2011/?id=121

1

UIImageView के साथ उच्च एफपीएस क्योंकि यह नहीं है वास्तव में redraws है, लेकिन केवल भविष्य जब में कभी कभी redrawing के लिए सामग्री के निशान UIKit ऐसा करने जैसा लगता है।

एक नोट के रूप में: हालांकि अजीब बात यह है कि CGContextmethod CALayermethod से तेज़ है। मैंने अपनी परियोजनाओं में इन तरीकों का भी प्रयास किया और कैलियर के साथ काम करना सबसे तेज़ तरीका है (कोर्स के ओपनजीएल ईएस को छोड़कर)।