2013-02-22 15 views
14

मैं एआरसी का उपयोग करके आईओएस ऐप लिख रहा हूं और आईओएस 5+ को लक्षित कर रहा हूं।एआरसी के तहत नील में प्रतिनिधियों को सेट करें?

मान लीजिए कि मैं एक कस्टम व्यू ऑब्जेक्ट लिखता हूं जिसमें एक प्रतिनिधि संपत्ति है। प्रतिनिधि संपत्ति घोषित करने में, मैं यह एक कमजोर संदर्भ के रूप में इस एक, चक्र को बनाए रखने के लिए इतना है कि जब वास्तविक प्रतिनिधि वस्तु (नियंत्रक) नष्ट हो जाता है, मेरे कस्टम दृश्य भी नष्ट हो जाएगा, से बचने के लिए करते हैं:

@interface MyCustomView : UIView 

@property (nonatomic, weak) id<MyCustomViewDelegate> delegate; 

@end 

सब अच्छा है।

ठीक है, तो अब मैं नियंत्रक ऑब्जेक्ट लिख रहा हूं, और इसमें दो दृश्य वस्तुओं का संदर्भ है: मेरा कस्टम व्यू और एक ऐप्पल-आपूर्ति यूआईकिट व्यू, जिनमें से दोनों प्रतिनिधि गुण घोषित करते हैं, और नियंत्रक प्रतिनिधि के लिए प्रतिनिधि है दोनों विचार

@interface MyViewController : UIViewController <MyCustomViewDelegate, UITableViewDataSource, UITableViewDelegate> 

@property (nonatomic, strong) MyCustomView *customView; 
@property (nonatomic, strong) UITableView *tableView; 

@end 

@implementation MyViewController 

- (void)viewDidLoad 
{ 
    self.customView.delegate = self; 
    self.tableView.dataSource = self; 
    self.tableView.delegate = self; 
} 

@end 

मेरा प्रश्न यह है:: शायद यह कुछ इस तरह दिखता मैं या तो या नहीं के बराबर करने के लिए दोनों प्रतिनिधियों स्थापित करने के लिए dealloc ओवरराइड करने के लिए की जरूरत है?

मेरा मतलब है, के रूप में मैं इसे समझ, UIKit देखने के प्रतिनिधि संपत्ति (इस मामले में, tableView) वास्तव में एक कमजोर संदर्भ, बल्कि एक __unsafe_unretained संदर्भ के लिए, एआरसी के साथ पीछे संगतता के लिए घोषित किया नहीं है आईओएस का संस्करण। तो शायद मैं

- (void)dealloc 
{ 
    _tableView.dataSource = nil; 
    _tableView.delegate = nil; 
} 

लिखने के लिए अब जरूरत है, अगर मैं dealloc ओवरराइड करने के लिए क्या है, मैं अभी भी _customView.delegate = nil, सही स्थापित करने के लिए नहीं है? क्योंकि यह घोषित किया गया था (मेरे द्वारा) एक कमजोर संदर्भ होने के लिए, इसलिए इसे MyViewController के विनाश पर स्वचालित रूप से शून्य करने के लिए सेट किया जाना चाहिए।

लेकिन दूसरी तरफ, मैं आईओएस के गैर-एआरसी संस्करणों को लक्षित नहीं कर रहा हूं, न ही मेरा इरादा है। तो शायद मुझे डेलोक को ओवरराइड करने की आवश्यकता नहीं है?

+0

आपको इस बारे में पता नहीं हो सकता है, लेकिन वर्तमान अनुशंसा यह है कि आईबीऑलेट्स * दृश्य पदानुक्रम में निहित * कमजोर होना चाहिए। दूसरे शब्दों में, यदि तालिका दृश्य दृश्य में निहित है, तो दृश्य मजबूत संदर्भ द्वारा आयोजित किया जाता है और तालिका दृश्य को होने की आवश्यकता नहीं होती है। इससे आपका मामला थोड़ा कृत्रिम बना देता है, हालांकि यह अभी भी उस मामले के लिए एक वैध सवाल है (जिसमें अन्य, अधिक वास्तविक उदाहरण हैं)। –

+0

@StevenFisher धन्यवाद, स्टीवन। मुझे इस बारे में पता था, लेकिन मेरे उदाहरण में, मैंने दृश्य गुणों को आईबीओटलेट घोषित नहीं किया; शायद मैं उन्हें आईबी के बजाय प्रोग्रामेटिक रूप से उत्पन्न कर रहा हूं। –

+0

@StevenFisher मुझे लगता है कि मैं '__weak' और '__unsafe_unretained' संपत्ति घोषणाओं के बीच का अंतर है, और आईओएस के पोस्ट-एआरसी संस्करणों को लक्षित करते समय उन अलग-अलग घोषणाओं के लिए मेरी ज़िम्मेदारी क्या है। –

उत्तर

30

नहीं के बराबर करने के लिए गैर कमजोर प्रतिनिधियों की स्थापना आम तौर पर एक अच्छा विचार है, जब तक कि आप जानते हैं आप की जरूरत नहीं है।

  1. स्क्रॉल वास्तव में तेजी से: UITableView और UIScrollView के लिए, मैं निम्न चरणों के साथ पिछले iOS संस्करण पर दुर्घटनाओं का अनुभव किया है (यह लाश को सक्षम करने पर चलाने के लिए मदद मिल सकती है)।
  2. पूर्ण हो गया या बैक बटन दबाएं या वीसी को खारिज करने के लिए जो भी हो।

ऐसा प्रतीत होता है क्योंकि स्क्रॉलिंग एनीमेशन दृश्य के संदर्भ को बनाए रखता है, इसलिए दृश्य वीसी से बाहर निकलता है। स्क्रॉल ईवेंट भेजते समय यह क्रैश हो जाता है।

मैं भी देखा है एक कुलपति एक UIWebView युक्त खारिज करते हुए एक अनुरोध लोड किया जा रहा है, जहां बस नहीं के बराबर करने के लिए प्रतिनिधि सेट करने के बाद दुर्घटनाओं पर्याप्त नहीं था (मुझे लगता है कि वैकल्पिक हल [webView loadRequest:nil] कॉल करने के लिए किया गया था)।

+0

क्या आपको यह केवल ऐसे मामलों में मिला है जहां आप ओआईटीबल व्यू कंट्रोलर का उपयोग ओपी की तरह नहीं कर रहे हैं? –

+0

@BobSpryn I dunno; मैंने ट्रैक नहीं रखा है (लेकिन आम तौर पर मैंने एक कस्टम वीसी का उपयोग किया है क्योंकि 'UITableViewController' पर्याप्त * लचीला नहीं है)। यह पूरी तरह से संभव है कि 'UITableViewController' तालिका दृश्य के डेटा स्रोत/प्रतिनिधि को '-dealloc' में सेट करता है। –

0

एकमात्र कारण आप स्पष्ट रूप से nil को delegate और dataSource सेट करना चाहते हैं, तो customView या tableView दृश्य नियंत्रक बाहर रह सकता है। उन्हें nil पर सेट करना delegate या dataSource के विरुद्ध एक डिलीओटेड ऑब्जेक्ट का संदर्भ देगा। customView और tableView दृश्य नियंत्रक के साथ पुनः आवंटित की जाती हो जाएगा

हैं, तो कोई जरूरत नहीं के बराबर करने के लिए बाहर delegate और dataSource है।

2

अगर केवल मजबूत संदर्भ कहा करने के लिए tableView अपने एकमात्र MyViewController नियंत्रक है, तो आप मैन्युअल nil को UITableViewDelegate या UITableViewDataSource निर्धारित करने की आवश्यकता नहीं है।

कारण यह है कि एक बार अपने MyViewController पर dealloc विधि कहा जाता है, tableview भी नियंत्रक के साथ नष्ट हो जाएगा है (अर्थात, एक बार फिर से, जब तक यह करने के लिए केवल संदर्भ के अपने एकमात्र नियंत्रक MyViewController वर्ग है) ।

यदि आपके पास अन्य नियंत्रकों जैसे इस तालिकादृश्य के अन्य मजबूत संदर्भ हैं, तो यह संभव होगा कि तालिकादृश्य MyViewController वर्ग से अधिक समय तक अस्तित्व में हो।इस तरह के एक मामले में, यह आवश्यक MyViewController की dealloc विधि में UITableViewDelegate और UITableViewDataSourcenil को स्थापित करने के लिए है क्योंकि, जैसा कि आप उल्लेख किया है, इन गुणों कमजोर संदर्भ नहीं हैं और स्वचालित रूप से nil करने के लिए सेट नहीं किया जाएगा होगा।

हालांकि, इस तरह की स्थिति मेरे अनुभव में बहुत दुर्लभ है।

अधिकांश समय, मैं इन्हें nil ईमानदारी से सेट करने के बारे में चिंता नहीं करता, लेकिन यह एक रक्षात्मक प्रोग्रामिंग अभ्यास है।

भी यह पोस्ट देखें:

In dealloc method set any delegate to nil is needed or not needed

+0

हमारे पास केवल कुछ सौ उपयोगकर्ताओं के साथ एक छोटा ऐप है, और मैं इस से संबंधित प्रति दिन 3-4 क्रैश देख रहा हूं। CoreAnimation स्टैक में है, इसलिए मुझे संदेह है कि एनीमेशन अपने नियंत्रक (प्रतिनिधि और डेटासोर्स) को मुक्त करने के बाद तालिका के मजबूत संदर्भ पर हो रहा है। हालांकि, मैंने इसे पुन: उत्पन्न करने में कामयाब नहीं रहा है। यदि आप UITableViewController का उपयोग कर रहे हैं और प्रतिनिधि और डेटा स्रोत UITableViewController पर सेट हैं, तो यह कोई समस्या नहीं हो सकती है। ऐप्पल ने इस मामले में डेलोक विधि में उन्हें साफ़ कर दिया। – Steve

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