2009-06-11 16 views
7

किसी उद्देश्य-सी उदाहरण के लिए परीक्षण/मुक्त होने के लिए परीक्षण करने का कोई तरीका है (गिनती == 0 बनाए रखें) ??ऑब्जेक्टिव-सी - ऑब्जेक्ट इंस्टेंस के लिए परीक्षण को हटा दिया गया/मुक्त किया गया

उदाहरण के लिए, ऑब्जेक्ट ए के पास बी ऑब्जेक्ट करने के लिए एक संदर्भ (सूचक) है, लेकिन ऑब्जेक्ट बी को स्मृति निम्न स्तरों में मुक्त किया जा सकता है, मैं यह सुनिश्चित करने के लिए संदर्भ बी का परीक्षण कैसे कर सकता हूं कि यह अस्वीकार कर दिया गया है ??

@interface A : NSObject { 
    B b; 
} 

@implementation A { 

- (void) someAction:(id) sender { 
    //is b previously dealloced?? 
    if ..... ???? { 
     b = [[B alloc] init]; 
    } 
    // continue 
} 
} 

धन्यवाद !!

+0

यह इस लेख की तरह लगता है आप दिखाई दे सकते हैं कि यह कैसे करना है: (http://blog.slaunchaman.com/2011/04/11/fun-with- [किसी भी वस्तु का आवंटन रद्द करने पर चलाने के कोड] उद्देश्य-सी-रनटाइम-रन-कोड-एट-डेलोकेशन-ऑफ-ऑब्जेक्ट) – Oscar

उत्तर

11

आप यह जांच नहीं सकते कि क्या ऑब्जेक्ट को हटा दिया गया है, जाहिर है, ऑब्जेक्ट अब और बात करने के लिए नहीं है। यदि आप इसे रिलीज़ करते समय b को शून्य पर सेट करते हैं (कहें, self.b = nil करके), हालांकि, आप शून्य के लिए परीक्षण कर सकते हैं और ऑब्जेक्ट बना सकते हैं।

+1

यह समस्या है, मैं ऑब्जेक्ट को स्पष्ट रूप से रिलीज़ नहीं करता हूं, यह फ्रेमवर्क कक्षाओं द्वारा जारी किया जाता है और यह अनुमानित समय के साथ नहीं होता है (उदा। didReceiveMemory चेतावनी: विधि कॉल) तो मुझे परीक्षण करने की जरूरत है कि मेरा संदर्भ (सूचक) अभी भी एक मान्य उदाहरण के लिए इंगित कर रहा है, अगर नहीं, आवंटित और एक नया init। – jlpiedrahita

+0

इस वर्ग के आवृत्ति चर को किस फ्रेमवर्क क्लास को जारी किया जा रहा है? इस वर्ग का अपना इवर क्यों नहीं है? मुझे लगता है कि आपको प्रश्न में अधिक जानकारी प्रदान करने की आवश्यकता हो सकती है। जैसा कि एलेक्स ने कहा, आपके गुण रहस्यमय तरीके से गायब नहीं होना चाहिए। – Chuck

2

यदि आप ठीक से बी बनाए रखते हैं, तो इसे कम स्मृति स्थितियों में हटाया नहीं जाएगा।

यही है, जब तक आप इसे अपने आप को deallocating कर रहे हैं, जिस स्थिति में यह महत्वपूर्ण है कि आप मैन्युअल रूप से कोई भी संदर्भ इसे करने के लिए इससे पहले कि आप ऐसा करते हैं

उस मामले में, बस इसे परीक्षण (शून्य और इसकी जगह द्वारा) को हटाने शून्य मूल्य के लिए क्या करेंगे:

if (nil == b) 
    { 
    reallocate b; 
    } 

ऐसा लगता है अपने वस्तुओं की तरह स्वचालित रूप से पुनः आवंटित की जाती किया जा रहा है, तो आप आप यह पर्याप्त रूप से बरकरार रखा है की जाँच करने के लिए अपने कोड की समीक्षा करने की जरूरत है।

0

आप dealloc विधि वस्तुओं में NSLog संदेशों को डालने का प्रयास कर सकते हैं। वस्तु कम होने पर कम से कम आपको बताएगा।

+0

यह देखने के लिए कोड में एक परीक्षण के लिए काम नहीं करेगा कि वस्तु को हटा दिया गया है या नहीं। सबसे अच्छा, यह डीबग करने में मदद करेगा कि बी से संबंधित रिटेन-रिलीज कोड (संभवतः) सही है। –

3

चर b के बाद से पूरी तरह से वर्ग A करने के लिए आंतरिक है, और (डिफ़ॉल्ट @protected है) सबसे अच्छा तरीका जानना चाहते हैं कि b पुनः आवंटित की जाती किया गया है इसे जारी और nil सूचक स्थापित करने के लिए है @public के रूप में घोषित नहीं है,। इस तरह, आप केवल if (b == nil) देख सकते हैं और यदि आवश्यक हो तो एक नया उदाहरण बना सकते हैं।

हालांकि, बड़ा सवाल यह है कि b की वास्तविक प्रकृति और स्मृति व्यवहार क्या है। आप बताते हैं कि "ऑब्जेक्ट बी को स्मृति कम स्तर में मुक्त किया जा सकता है", लेकिन क्यों नहीं समझाओ। यदि आप उद्देश्य-सी में बनाए रखने के लिए मानक मुहावरे का उपयोग कर रहे हैं, तो मुझे लगता है कि बी यह निर्धारित करने वाला होगा कि बी को हटाया जाना चाहिए, क्योंकि यह एक नया उदाहरण बना रहा है। यदि आप इस तरह के फैसले करने के लिए ए का इरादा नहीं रखते हैं, तो इसे एक नया बी आवंटित करने की इजाजत दी जाएगी जिससे सड़क पर स्वामित्व भ्रम और स्मृति कीड़े हो जाएंगी।

तो एक नहीं बी के आरोप में, और अगर आप तेंदुए पर हैं (या परे) और कचरा संग्रहण सक्षम किया है, एक कमजोर संदर्भ शून्यीकरण को क्या आप चाहते हो सकता है है। यह एक उदाहरण परिवर्तनीय घोषणा से पहले __weak का उपयोग करके घोषित किया गया है, और कचरा कलेक्टर को उस ऑब्जेक्ट को एकत्रित करने से नहीं रोकता है जो इसे इंगित करता है। (एक "मजबूत" संदर्भ डिफ़ॉल्ट है, और कचरा कलेक्टर ऑब्जेक्ट को डिलीकेट नहीं करेगा, यह रूट से केवल मजबूत संदर्भों के माध्यम से पता लगा सकता है।) आगे, जीसी स्वचालित रूप से 0 के लिए कमजोर संदर्भ सेट कर देगा यदि ऑब्जेक्ट है deallocated।

"बड़े प्रश्न" पर वापस आ रहा है, जब तक b पहले से ही एक कमजोर संदर्भ नहीं है और जीसी चालू है, (और कुछ अन्य स्थितियां हैं), सिस्टम स्वचालित रूप से आपके लिए बी को निष्क्रिय नहीं करेगा।यदि b को हटाने का कारण यह है कि बी के समय बी के साथ बढ़ते हैं, (जैसे कि डिस्पेंस करने योग्य वस्तुओं का कैश), तो खाली होने का तरीका बेहतर होगा। उदाहरण के लिए, फाउंडेशन में उत्परिवर्तनीय संग्रह में -removeAllObjects विधि है। इस तरह का एक दृष्टिकोण इस बारे में भ्रम से बच जाएगा कि b अभी भी मौजूद है या नहीं, और बार-बार (डी) ऑब्जेक्ट आवंटित करने से कहीं अधिक कुशल है।

+0

टैग कोको टच कहते हैं, इसलिए वह तेंदुए पर नहीं है। – Chuck

+0

टैग में से एक भी "कोको" है, और सवाल ने आईफोन निर्दिष्ट नहीं किया है, इसलिए मैं सामान्य होने के लिए सबसे अच्छा हूं और "अगर" तेंदुए पर होने वाले लोगों के लिए सहायक हो सकता हूं। –

13

यदि आप NSZombieEnabled पर्यावरण चर सेट करते हैं, तो हटाए गए ऑब्जेक्ट NSZombie के उदाहरण बन जाते हैं। ये फेंकते हैं जब वे अगली संदेशित होते हैं, जिससे आपका कोड क्रैश हो जाता है और जला दिया जाता है - वास्तव में आपको इस स्थिति को डीबग करने की आवश्यकता होती है।

http://www.cocoadev.com/index.pl?DebuggingAutorelease

अद्यतन: XCode 4.0 के लिए देखें How to enable NSZombie in Xcode?

+0

वाह, बस मुझे आज क्या चाहिए। धन्यवाद! –

-3

ही किसी "की कोशिश-पकड़" काम करता है?

@try { 
     [b description]; // test it... 
} 
@catch (NSException * e) { 
    NSLog(@"Exception: %@", e); 
} 
@finally { 
    NSLog(@"finally"); 
} 
+0

यह होगा लेकिन यह गरीब आदमी का फिक्स – Mel

+1

है कि एक निश्चित उदाहरण पर एक संदेश को कॉल करने के लिए निश्चित रूप से एक सिग्बार्ट को सामान्य अपवाद फेंक नहीं देता है। –

+2

-1 deallocated उदाहरण के लिए अपवाद फेंक नहीं है। – Raptor

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