2012-02-09 12 views
7

मुझे पता है कि मैं जिस समस्या को रेखांकित करने जा रहा हूं उसे ठीक करने के लिए, हालांकि, मैं थोड़ा सा परेशान हूं कि आईओएस सिम्युलेटर में कोड परिदृश्य क्यों काम करता है लेकिन मेरे आईपैड पर नहीं।आईओएस सिम्युलेटर में आईओएस सिम्युलेटर में एक CGColor प्रॉपर्टी काम करने के लिए मौजूदा CGColor को असाइन करना। क्यूं कर?

मेरे पास एक विधि है जो विभिन्न गुणों की जांच करती है, और उसके बाद संपत्ति की स्थिति के आधार पर CALayer का पृष्ठभूमि रंग सेट करती है। निम्नलिखित कोड रंग असाइनमेंट की मेरी विधि के समान है:

//This will be the CALayer BGColor... 
CGColor c = UIColor.blueColor.CGColor; //Blue is the default 
switch (myState) 
{ 
    case state_one: 
     c = UIColor.greenColor.CGColor; 
     //... more code ... 
     break; 
    case state_two: 
     c = UIColor.redColor.CGColor; 
     //... more code ... 
     break; 
    case state_three: //multiple cases are like the state_three case. 
     //Other code, but I don't need to assign the color. Blue works... 
} 

myCALayer.backgroundColor = c; //Oh-noes!!! Here we get the dreaded EXC_BAD_ACCESS on iPad 
//...more code dealing with the layer. 

उपरोक्त कोड सिम्युलेटर में बिना किसी परेशानी के काम करता है। हालांकि, जब मैं अपने आईपैड पर एप्लिकेशन चलाता हूं, तो यह backgroundColor असाइनमेंट पर दुर्घटनाग्रस्त हो जाता है।

मैं इसे CGColor चर से छुटकारा पाने और सीधे मेरे स्विच/केस स्टेटमेंट के भीतर से पृष्ठभूमि रंग असाइन करके इसे ठीक कर सकता हूं, और यही वह है जो मैं करने की योजना बना रहा हूं।

हालांकि, मैं उत्सुक हूं। यह एक पर्यावरण में क्यों काम करेगा, न कि दूसरे?

अद्यतन

युगल बातें। सबसे पहले, यह उल्लेखनीय है कि यह आईओएस 5 उपकरणों को लक्षित करने, एक्सकोड 4.2 का उपयोग करके एक एआरसी परियोजना है। साथ ही, मेरा रंग असाइनमेंट कोड पूरी तरह से ऐसा नहीं दिखता है क्योंकि मेरे पास ऐसा परिभाषा है जो मैं इन रंगों को सेट करने के लिए उपयोग करता हूं क्योंकि उन्हें मेरे पूरे एप्लिकेशन में संदर्भित किया जाता है।

#define BLUE [UIColor colorWithRed:8.0/255.0 green:80.0/255.0 blue:150.0/255.0 alpha:1.0].CGColor 
#define GREEN (UIColor.blueColor.CGColor) 
//...and there are about 6 other colors 

मैं अपने कोड को आसान बनाने की वजह संकलक मेरी परिभाषित करने के लिए अपने refs को refs बदलना चाहिए की कोशिश की:

यह वही है #define बयान के कुछ ही लग रहा है की तरह है। फिर भी, मामले में बस उल्लेख करने लायक है।

+0

आप प्रत्येक निर्माण में QuartzCore ढांचा शामिल करना न भूलें की थी? –

+1

मेरा 'CGColor' के साथ भी निर्माण नहीं करेगा, शायद आपका मतलब 'CGColorRef' –

+0

मैंने ढांचा जोड़ा है, और हेडर को कोड फ़ाइल के भीतर से संदर्भित किया है जो इस असाइनमेंट को बना रहा है। – RLH

उत्तर

8

यहां मेरा झुकाव है: यह संभव है कि UIColor जिसने इसे बनाया है (और इसका एकमात्र संदर्भ) CGColor पास करने से पहले नष्ट कर दिया गया है। चूंकि CGColorRef की संदर्भ गणना आपके लिए एआरसी के तहत नहीं की जाती है, इसलिए UIColor पर रंग एक खतरनाक संदर्भ होगा यदि CGColor का उपयोग करने से पहले इसे नष्ट कर दिया गया था।

एआरसी में एक अनुकूलन है जहां ओबजेक ऑब्जेक्ट का संदर्भ नहीं दिया गया है, इसके बाद "ऑटोरेलेज्ड" ऑब्जेक्ट्स को ऑटोरेलीज पूल में कभी भी जोड़ा नहीं जा सकता है, और इसके बजाय released। यह तीन चीजों का संयोजन है:

  1. आपके द्वारा उपयोग किए जाने वाले कंपाइलर संस्करण और विकल्प। कोई आश्चर्य नहीं, संकलक संदर्भ गणना जोड़ता है, और इसके लिए भिन्नताएं हैं।
  2. ओबीजेसी रनटाइम। रनटाइम थ्रेड स्थानीय डेटा का उपयोग कर सकता है। स्वाभाविक रूप से, इसमें आपका ढेर शामिल हो सकता है।यदि आप एक ऑब्जेक्ट पूल को कैसे बाईपास कर सकते हैं, इस बारे में विवरण में पढ़ा है, तो यह स्पष्ट होना चाहिए।
  3. आपके द्वारा उपयोग की जाने वाली लाइब्रेरीज़ (सिस्टम लाइब्रेरीज़ और फ्रेमवर्क सहित)। चूंकि कंपाइलर और रनटाइम्स अपडेट किए जाते हैं, इसलिए पुस्तकालय एआरसी का उपयोग कर सकते हैं, या वे प्रोग्राम को निष्पादित करने के लिए विभिन्न रनटाइम कॉल का उपयोग कर सकते हैं।

यह जानते हुए कि, मुझे लगता है इस कार्यक्रम के समस्या को सुधारने होगा:

UIColor * c = UIColor.blueColor; //Blue is the default 
switch (myState) { 
    case state_one: 
     c = UIColor.greenColor; 
     //... more code ... 
     break; 
    case state_two: 
     c = UIColor.redColor; 
     //... more code ... 
     break; 
    case state_three: //multiple cases are like the state_three case. 
     //Other code, but I don't need to assign the color. Blue works... 
} 

myCGLayer.backgroundColor = c.CGColor; 
//...more code dealing with the layer. 

और अधिक विस्तार में, वहाँ तरीके की संख्या संकलक और ObjC क्रम व्याख्या और अपने कार्यक्रम पर अमल कर सकते हैं। इसका अर्थ यह है कि जब आप कंपाइलर संस्करण बदलते हैं, या जब रनटाइम (ओएस) अपडेट किया जाता है तो यह समस्या आपको प्रभावित कर सकती है। यह भी हो सकता है क्योंकि आपके द्वारा उपयोग की जाने वाली लाइब्रेरी को विभिन्न संस्करणों या कंपाइलर सेटिंग्स के साथ अपडेट या बनाया गया है। उदाहरण के लिए: यदि पुस्तकालय एआरसी के साथ स्विच करता है, तो यह एक अलग रनटाइम कॉल का उपयोग कर सकता है, या यदि संकलक इंजेक्शन कॉल अपडेट होते हैं तो कॉल थ्रेड स्थानीय डेटा का अलग-अलग उपयोग कर सकते हैं।

एआरसी कल्पना के रूप में यह क्रम से संबंधित है के बारे में विवरण यहां पाया जा सकता: एआरसी रंग की वजह से

EXC_BAD_ACCES drawing shadow

+0

संदेश को अनदेखा करें जिसे मैंने अभी हटा दिया है। जादू! इसने समस्या को ठीक कर दिया है। क्या क्वार्ट्जकोर आईओएस से ओएसएक्स पर मेमोरी प्रबंधित करता है, इस तरह के महत्वपूर्ण अंतर हैं? यह पहली बार नहीं है जब मैंने दोनों के बीच नाबालिग, स्मृति प्रबंधन विषमताएं देखी हैं, लेकिन यह निश्चित रूप से सबसे अजीब रहा है। – RLH

+0

@RLH यह क्वार्ट्ज नहीं है - यह एआरसी और कंपाइलर के साथ है (यह मेरा हंच है - मैं अभी तक असली परियोजनाओं में एआरसी का उपयोग नहीं करता हूं, और इस @ 100% की पुष्टि करने के लिए ओबीजेसी रनटाइम के नवीनतम कार्यान्वयन को नहीं पढ़ा है) । रनटाइम कुछ मामलों में थ्रेड स्थानीय भंडारण का उपयोग करता है; ऑब्जेक्ट जो * एमआरसी में ऑटोरेलेज्ड किया जाएगा, कभी भी ऑटोरेलीज पूल में नहीं जोड़ा जा सकता है। इसके बजाए, कंपाइलर कुछ रनटाइम्स के तहत रिलीज संदेश के परिणामस्वरूप जोड़ देगा (स्वाभाविक रूप से, यह आपके द्वारा उपयोग किए जाने के बाद होता है)।मैंने इसके कार्यान्वयन के संबंध में कुछ और विवरणों के लिए मेरे उत्तर में एक लिंक जोड़ा है। – justin

+0

लिंक के लिए धन्यवाद और मैंने इसे उत्तर के रूप में चिह्नित किया है क्योंकि मुझे संदेह है कि एक प्रत्यक्ष (समझदार) उत्तर है, जब तक कि यहां कोई भी व्यक्ति इन ढांचे या कंपाइलरों के लिए ऐप्पल मालिकाना कोड के साथ काम नहीं करता है। आपका लेख गहरा दिखता है - मैं इसे इस सप्ताह के अंत में देख लूंगा। – RLH

0

आप यह नहीं कहते कि आपका उदाहरण myCGLayer हमें किस प्रकार से लिया गया है, लेकिन मैं एक शॉट ले जाऊंगा और कहूंगा कि यह CGLayer से नहीं लिया गया है, क्योंकि CGLayer में backgroundColor संपत्ति नहीं है। तो मैं अनुमान लगा रहा हूं (दोबारा), पारित पैरामीटर यूआईसीओलर का प्रकार होना चाहिए और CGColor नहीं होना चाहिए। CGColor क्लास CFType से लिया गया है। यूआईसीओलर एनएसओब्जेक्ट से लिया गया है। उन्हें अदला-बदली नहीं किया जाना चाहिए। अगर मेरे अनुमान सही हैं, तो मुझे आश्चर्य है कि यह सिम्युलेटर में काम करता है।

यदि मेरे अनुमान गलत हैं तो मुझे बहुत कठोर न करें।

+0

शायद वे कैलियर का मतलब था। उन्होंने वास्तव में वर्णन में कैलियर कहा। – Chuck

+0

प्रयास के लिए धन्यवाद, लेकिन यह मेरी गलती थी। मैंने उस नमूना कोड में टाइप किया, इसलिए, कोई कट-एंड-पेस्ट नहीं। चक सही है - यह एक 'कैलियर' है। मैंने इसे प्रतिबिंबित करने के लिए नमूना में अपना चर अद्यतन किया है। – RLH

+0

इससे कोई फर्क पड़ता है (यदि असली कोड में टाइपो का प्रकार नहीं है)। – Jim

4

: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#runtime


ऐसा ही एक समस्या यहाँ देखा गया था विधि के अंत में बहुत जल्दी जारी किया जाता है।

मैं का उपयोग करें: CGColorRetain

CGColorRef whiteColor = CGColorRetain([UIColor colorWithRed:1.0 green:1.0 
             blue:1.0 alpha:1.0].CGColor);