2011-01-12 4 views
7

के बीच व्यवहार अंतर मेरे पास एक आईफोन ऐप में कोड का एक टुकड़ा है, जो UIView सबक्लास से सभी सबव्यूव को हटा देता है। ऐसा लगता है:UIView.subviews और [NSView सबव्यूज़]

NSArray* subViews = self.subviews; 
for(UIView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 

यह ठीक काम करता है। वास्तव में, मैं वास्तव में कभी नहीं सोचा था कि यह बहुत दे दी है जब तक मैं लगभग (एक NSView उपवर्ग से) एक मैक ओएस एक्स अनुप्रयोग में एक ही बात करने की कोशिश की:

NSArray* subViews = [self subviews]; 
for(NSView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 

कि पूरी तरह से काम नहीं करता। विशेष रूप से, क्रम में, मैं इस मिल:

*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated. 

मैं इतना है कि यह कर समाप्त हो गया:

NSArray* subViews = [[self subviews] copy]; 
for(NSView *aView in subViews) { 
    [aView removeFromSuperview]; 
} 
[subViews release]; 

यही ठीक है। मुझे क्या परेशान कर रहा है, हालांकि, यह आईफोन पर क्यों काम करता है?

@property(nonatomic,readonly,copy) NSArray *subviews; 

मेरी पहली सोचा था, हो सकता है @ synthesize'd ही टिककर खेल एक प्रति लौटने जब प्रतिलिपि विशेषता निर्दिष्ट किया जाता है:

subviews एक प्रति संपत्ति है। The doc सेटर्स के लिए प्रतिलिपि के अर्थशास्त्र पर स्पष्ट है, लेकिन गेटर्स के लिए कोई रास्ता नहीं दिखता है (या कम से कम, यह मेरे लिए स्पष्ट नहीं है)। और वास्तव में, मेरे अपने कुछ परीक्षण कर रहे हैं, यह स्पष्ट रूप से मामला प्रतीत नहीं होता है। जो अच्छा है, मुझे लगता है कि एक प्रतिलिपि कुछ कारणों से समस्याग्रस्त हो जाएगी।

तो सवाल यह है कि उपरोक्त कोड आईफोन पर कैसे काम करता है? NSView स्पष्ट रूप से सबव्यूज़ की वास्तविक सरणी में एक सूचक लौटा रहा है, और शायद UIView नहीं है। शायद यह केवल UIView का कार्यान्वयन विवरण है, और मुझे इसके बारे में काम नहीं करना चाहिए।

क्या कोई भी अंतर्दृष्टि प्रदान कर सकता है?

उत्तर

13

यह -[NSView subviews] में एक बग है। मैं शपथ ले सकता था कि यह हिम तेंदुए के लिए तय किया गया था, लेकिन अब कोई सबूत नहीं मिल रहा है।

सौभाग्य से, वहाँ एक आसान तरीका सभी subviews दूर करने के लिए है:

[self setSubviews:[NSArray array]]; 
+3

यह मुश्किल से एक बग @Mike है। यह सिर्फ [someNSView सबव्यूव्यू] सबव्यूज़ की सरणी में पॉइंटर लौटाता है, जबकि [someUIView सबव्यूज़] उस सरणी की प्रति देता है। यही कारण है कि यह आईओएस पर ठीक काम करता है। – jackal

2

हां, यह ठीक है कि ऐप्पल ने इसे कैसे कार्यान्वित किया। मैक पर, सबव्यू व्यू द्वारा उपयोग की जाने वाली वास्तविक (म्यूटेबल) सरणी देता है, इसलिए आप दृश्य जोड़ने या हटाने के दौरान तेज़ गणना का उपयोग नहीं कर सकते हैं। यदि आप reverseObjectEnumerator का उपयोग करना चाहते हैं, तो आप सक्षम हो सकते हैं। सामान्य गणनाकर्ता का उपयोग न करें क्योंकि यह उप-दृश्यों को छोड़ सकता है क्योंकि वे हटाए गए लोगों को बदलने के लिए स्थानांतरित हो जाते हैं। आईओएस में, हालांकि, ऐप्पल ने इस समस्या को महसूस किया है और इसे एक प्रतिलिपि स्वचालित रूप से वापस कर इसे ठीक कर दिया है। संपत्ति घोषणा केवल वर्णन करती है कि यह कैसे सेट किया गया है, लेकिन सेब ने भी गेटर के लिए प्रतिलिपि बनाना चुना।

3

बेहतर उपयोग

while([self.subviews count] > 0){ 
    [[self.subviews objectAtindex:0] removeFromSuperview]; 
} 

आशा इस मदद करते हैं।

संबंधित मुद्दे