2012-01-01 8 views
5

मैं एक फिक्स लंबाई परिवर्तनशील सामग्री साझा डेटा बफर करना चाहते हैं और है कि मैं इसे कैसे बना सकता हूँ है:व्यवहार: लंबाई: freeWhenDone:

void *buffer = malloc(length); 
// initialize buffer content 
NSData *sharedData = [[NSData alloc] initWithBytesNoCopy:buffer length:length freeWhenDone:YES] 

क्या के बाद मैं एक बनाया है कि अगर मैं buffer संशोधित एनएसडीटा से? क्या एनएसडीटा buffer पर किए गए परिवर्तन को प्रतिबिंबित करेगा?

मैं गारंटी दे सकता हूं कि sharedData जब मैं buffer को संशोधित करना चाहता हूं तो डीलोक नहीं मिलेगा।

यह कैसे मैं वास्तव में इसका उपयोग करना चाहते है:


void *my_alloc(CFIndex allocSize, CFOptionFlags hint, void *info) {return NULL;} 
void my_dealloc(void *ptr, void *info) { 
    mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)ptr, (size_t)info); 
} 

size_t length = //some number 
mach_vm_address_t buffer; 
mach_vm_allocate(mach_task_self(), &buffer, length, VM_FLAGS_ANYWHERE); 
// do something to buffer, for example pass to other process using mach RPC and expect other process will modify the content 
CFAllocatorContext context = {0, (void *)length, NULL, NULL, NULL, my_alloc, NULL, my_dealloc, NULL}; 
CFAllocatorRef allocator = CFAllocatorCreate(NULL, &context); 
CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)buffer, length, allocator); 

उत्तर

7

initWithBytesNoCopy: प्रभावी ढंग से मौजूदा बफर के चारों ओर एक NSData आवरण पैदा करेगा; तो हाँ, [sharedData bytes] के माध्यम से पहुंचने वाली चीजें आपके द्वारा किए गए कोई भी अपडेट देखेंगे।

बेशक

, यह अन्य वस्तुओं जो NSData उदाहरण से बनाई गई हैं लिंक करने के लिए तो उदाहरण के लिए एक [NSImage initWithData:sharedData]NSImage उदाहरण है, जो किसी भी परिवर्तन को प्रतिबिंबित नहीं करेगा के लिए एक प्रतिलिपि बना सकता है कुछ नहीं करता है।

इसके अलावा

, freeWhenDone:YES साथ NSData बफर जब पिछले संदर्भ निकाल दिया जाता है को नष्ट कर देगा, तो विचार किया जा सकता =)


तो, यह देखते हुए कि NSData प्रभावी रूप से एक malloc() आवंटन चारों ओर एक पतली आवरण है , हाँ यह उस स्मृति में किए गए परिवर्तनों को प्रतिबिंबित करेगा (किसी भी प्रक्रिया से); लेकिन चूंकि यह free() पर कॉल करेगा, तो freeWhenDone:YES के साथ एक बफर को लपेटने के लिए इसका उपयोग करना एक बुरा विचार है (mach_vm_allocate)।

तुम सच-सच में एक कस्टम संभाजक उपयोग करने की आवश्यकता नहीं है, तो मुझे लगता है कि आप के साथ बेहतर होगा (क्यों?):

NSMutableData* sharedData = [NSMutableData dataWithCapacity:length]; 
// `dataWithLength:` will fully allocate and zero the buffer first, if you prefer 
void* buffer = [sharedData mutableBytes]; 
// do something to `buffer`, mach RPC, etc. 
// 3: profit. 
संबंधित मुद्दे