2013-08-14 5 views
9

के साथ एक शून्य * सूचक में उद्देश्य-सी ऑब्जेक्ट असाइन करना मुझे शून्य * सूचक में एक सी संरचना में एक उद्देश्य सी ऑब्जेक्ट रखने की आवश्यकता है। यह संरचना बाहरी पुस्तकालय में परिभाषित है और मैं परिभाषा को बदल नहीं सकता।एआरसी

मान लें कि यह के रूप में परिभाषित किया गया है दो:

struct c_context { 
    void* user_data; 
}; 

और क्या मैं अपने कोड में क्या करने की जरूरत यह है:

struct c_context *context; 
... 
context->user_data = [[MYObjCClass alloc] init]; 

हालांकि, मुझे यकीन है कि MYObjCClass वस्तु हो जाएगा बनाने की जरूरत है बनाए रखा।

तो मेरे सवाल है:

  1. कैसे void* को कास्ट करने के लिए (या पुल) यह Obj सी वस्तु बनाए रखने के लिए संकलक बता रहा?
  2. जब मुझे डेटा साफ़ करने की आवश्यकता होती है तो ऑब्जेक्ट को बाद में कैसे रिलीज़ किया जाए?

उत्तर

12

You cannot use ARC to manage an object in a struct. आप मैन्युअल रूप से इसके मेमोरी प्रबंधन को ट्रैक करने के लिए ज़िम्मेदार हैं। आप इस तरह वस्तुओं को संग्रहित करने से निराश हैं।

आप स्मृति इस तरह से ट्रैक करना चाहिए, तो आप एआरसी है कि आप वस्तु के लिए जिम्मेदारी ले जा रहे हैं जब आप इसे struct में डाल बताना होगा:

context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]); 

यह एआरसी बताता है यह अब जिम्मेदार है कि के लिए ऑब्जेक्ट init द्वारा लौटाया गया, और एक मैनुअल retain जोड़ता है ताकि context->user_data अब मालिक हो।

जब आप ऑब्जेक्ट के साथ होते हैं, तो आप इसे वापस एआरसी में स्थानांतरित कर सकते हैं, या आप इसे छोड़ सकते हैं। एआरसी को इसे वापस स्थानांतरित करने के लिए:

MYObjCClass *something = CFBridgingRelease(context->user_data); 
context->user_data = NULL; 

यह एआरसी बताता है यह वस्तु के लिए जिम्मेदार है और अपने को बनाए रखने को हटा। आपको पॉइंटर को पूर्ण करना चाहिए क्योंकि context->user_data अब इस ऑब्जेक्ट का मालिक नहीं है और ऑब्जेक्ट किसी भी समय गायब हो सकता है।

तुम भी सीधे इसे जारी कर सकते हैं:

CFRelease(context->user_data); 
context->user_data = NULL; 

फिर, यह एक अंतिम उपाय तकनीक है। आम तौर पर आपको ओआरजेसी वस्तुओं को structs में स्टोर नहीं करना चाहिए क्योंकि एआरसी उन्हें प्रबंधित नहीं कर सकता है।

एक साइड नोट के रूप में, जबकि मैं आम तौर पर ओबीजेसी ++ की अनुशंसा नहीं करता हूं, तो इसे स्वचालित करने के लिए एक विनाशक के साथ सी ++ संरचना का उपयोग करना संभव है। कुछ मामलों में, यह सी

+1

में मैन्युअल रूप से मेमोरी प्रबंधन के लिए बेहतर हो सकता है CFBridging (__bridge_retained void *) और CFBridgingRelease के रूप में समान है (__bridge_transfer MYObjCClass *)? – Dmitry

+1

हां, लेकिन सीएफब्रिजिंग * मैक्रोज़ यह और अधिक स्पष्ट करते हैं कि क्या हो रहा है। –

+0

ग्रेट। बहुत बहुत धन्यवाद, रोब। अब यह बहुत स्पष्ट है – Dmitry