2012-03-17 15 views
7

मैं दो दृश्यों को जोड़ रहा हूं, जो गुणों द्वारा संग्रहीत हैं, मेरे विचार में। मेरे दृश्य में सबव्यू जोड़ते समय मेरे setup विधि के बाद सबव्यूज़ को विलुप्त कर दिया जाता है। अंत परिणाम यह है कि विचार कभी प्रदर्शित नहीं होते हैं। अब, अगर मैं weak के विरोध में strong पर अपनी गुणों को बदलता हूं, तो मैं दृश्यों का संदर्भ बनाए रखता हूं और अब वे स्क्रीन पर दिखाते हैं। तो यहाँ क्या चल रहा है? addSubview: और insertSubview: सबव्यूज़ को बनाए रखने क्यों नहीं है?addSubview क्यों है: दृश्य को बनाए रखना नहीं है?

btw

, मैं एआरसी (इसलिए मजबूत और कमजोर सामान) के साथ iOS5 उपयोग कर रहा हूँ

#import "NoteView.h" 
@interface NoteView() <UITextViewDelegate> 
@property (weak, nonatomic) HorizontalLineView *horizontalLineView; // custom subclass of UIView that all it does is draw horizontal lines 
@property (weak, nonatomic) UITextView *textView; 
@end 

@implementation NoteView 
@synthesize horizontalLineView = _horizontalLineView; 
@synthesize textView = _textView; 

#define LEFT_MARGIN 20 
- (void)setup 
{ 
    // Create the subviews and set the frames 
    self.horizontalLineView = [[HorizontalLineView alloc] initWithFrame:self.frame]; 
    CGRect textViewFrame = CGRectMake(LEFT_MARGIN, 0, self.frame.size.width, self.frame.size.height); 
    self.textView = [[UITextView alloc] initWithFrame:textViewFrame]; 


    // some addition setup stuff that I didn't include in this question... 

    // Finally, add the subviews to the view 
    [self addSubview:self.textView]; 
    [self insertSubview:self.horizontalLineView atIndex:0]; 
} 

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 

    [self setup]; 
} 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
     [self setup]; 
    } 
    return self; 
} 
+0

आप कैसे पैदा कर रहे नोटव्यू का उदाहरण ?? नियंत्रण का नियंत्रण सेटअप में पहुंच रहा है .. –

+0

मैं स्टोरीबोर्ड में दृश्य नियंत्रक में जोड़कर नोटव्यू का उदाहरण बना रहा हूं। –

+0

क्या आप क्लास को Xib में नोटिव्यू –

उत्तर

21

अपने कोड की एक पंक्ति है। एआरसी उत्पन्न होने वाले अतिरिक्त कोड के साथ, उस पंक्ति में वास्तव में क्या होता है, इसके माध्यम से चलो चलें। सबसे पहले, आप alloc और initWithFrame: तरीकों भेजने के लिए, एक मजबूत संदर्भ वापस पाने:

id temp = [[HorizontalLineView alloc] initWithFrame:self.frame]; 

इस बिंदु पर, HorizontalLineView वस्तु, के 1. अगला गिनती बनाए रखने है horizontalLineView गुण सेट करने के लिए है क्योंकि आप डॉट वाक्य रचना का इस्तेमाल किया , संकलक setHorizontalLineView: विधि self पर पैरामीटर के रूप में temp पास करने के लिए कोड उत्पन्न करता है। चूंकि HorizontalLineView संपत्ति weak घोषित किया जाता है, सेटर विधि से करता है:

objc_storeWeak(&self->_horizontalLineView, temp); 

कि self->_horizontalLineViewtemp के बराबर सेट, और कमजोर संदर्भ की वस्तु की सूची पर &self->_horizontalLineView डालता है। लेकिन यह HorizontalLineView ऑब्जेक्ट की बनाए रखने की गिनती को बढ़ाता है।

अंत में, temp चर नहीं रह गया है इसलिए आवश्यक है क्योंकि, संकलक इस उत्पन्न करता है:

[temp release]; 

कि HorizontalLineView वस्तु की बनाए रखने शून्य करने के लिए गिनती को कम करती है, तो यह वस्तु deallocates। निर्वासन के दौरान, यह कमजोर संदर्भों की सूची में चलता है, और प्रत्येक को nil पर सेट करता है। तो self->_horizontalLineViewnil बन जाता है।

तरह से इसे ठीक करने के temp चर स्पष्ट बनाने के लिए, ताकि आप अपने जीवन का विस्तार कर सकते हैं के बाद जब तक आप अपने superview है, जो इसे बरकरार रखे हुए है करने के लिए HorizontalLineView वस्तु को शामिल किया है है:

HorizontalLineView *hlv = [[HorizontalLineView alloc] initWithFrame:self.frame]; 
self.horizontalLineView = hlv; 
// ... 
[self insertSubview:hlv atIndex:0]; 
+2

वाह - आप बिल्कुल सही हैं! यह सटीक प्रकार का स्पष्टीकरण है जिसे मैं उम्मीद कर रहा था कि दृश्य के पीछे क्या हो रहा है। क्या यह अजीब प्रतीत नहीं होता है कि आपको स्पष्ट चर बनाने के अतिरिक्त चरण में जाना है? किसी भी मामले में, मदद के लिए धन्यवाद! –

+0

मैंने पाया कि यह केवल एक अस्थायी चर प्रस्तुत करने के लिए पर्याप्त है, आपको 'insertSubview'' पर कॉल में इसका उपयोग करने की आवश्यकता नहीं है। तो आप '[self insertSubview: self.horizontalLineView atIndex: 0] का उपयोग कर सकते हैं; 'और यह अभी भी काम करता है। यह मुझे काउंटर सहज महसूस करता है। क्या आप इस व्यवहार को समझा सकते हैं? –

3

कमजोर मामलों में जहां एक अभिभावक-बच्चे को बनाए रखने में जब तक नहीं किया जाना चाहिए चक्र है: नीचे कोड देखें गठित (माता-पिता बच्चे के लिए संदर्भ रखता है, बच्चा माता-पिता का संदर्भ रखता है, इसलिए न तो हटा दिया जाता है)। स्ट्रॉन्ग एआरसी बराबर है (अब एआरसी के तहत अमान्य है), और कमजोर संदर्भ की तुलना में ऑब्जेक्ट में एक अच्छा स्थिर सूचक रहता है, इसलिए addSubview वास्तव में आपको किसी प्रकार की त्रुटि देने के बजाय काम करता है।

addSubview क्यों है: और insertSubview: सबव्यूज़ को बनाए रखना क्यों नहीं है?

क्या आपने कभी किसी शून्य ऑब्जेक्ट पर कॉल करने का प्रयास किया है? हाँ, अभी भी शून्य। आपका कमजोर संदर्भ UIView ऑब्जेक्ट को ऑब्जेक्ट पर सफलतापूर्वक 'कॉल बनाए रखने' के लिए पर्याप्त समय तक नहीं रख रहा है। कि horizontalLineView संपत्ति कमजोर है

self.horizontalLineView = [[HorizontalLineView alloc] initWithFrame:self.frame]; 

याद:

+0

के रूप में निर्दिष्ट किया गया है क्यों यह क्रैश होगा? –

+0

मुझे लगता है कि एक विलुप्त उदाहरण को बरकरार रखने के लिए ... – CodaFi

+0

मेरा मतलब है कि मैं देख रहा हूं कि आप क्या कह रहे हैं कि विचारों को बनाए रखने के लिए कितने समय तक रखा नहीं जा सकता है, लेकिन (पैरेंट) दृश्य के बाद सेटअप विधि को कॉल किया जाना चाहिए instantiated। तो जब मैं दृश्य पदानुक्रम में अपने सबव्यूव्स जोड़ता हूं तो वे बनाए जाते हैं, है ना? तो मुझे लगता है कि मैं अभी भी उलझन में हूं। मैं क्या खो रहा हूँ? –

0

बजाय इस उपयोग करके देखें:

@property (nonatomic, retain) 
+0

बरकरार आर्क के तहत अमान्य है, और वह एक स्पष्टीकरण मांग रहा था। – CodaFi

+0

@ कोडाफ़ी, संपत्ति बनाए रखना एआरसी के तहत पूरी तरह मान्य है। –

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