2012-04-18 17 views
17

के लिए वेक्टर वहाँ एक अच्छा तरीका NSNumber के NSArray करने के लिए एक vector<int32_t> कन्वर्ट करने के लिए है या पाशन और एक NSMutableArray काफी एक ही रास्ता करने के लिए जोड़ रहा है?परिवर्तित एसटीडी: NSArray

+0

एनएसएआरएआरई में आदिम प्रकार एनएसआईएनटेगर के तत्व नहीं हो सकते हैं। –

+1

@ रिचर्ड जे। रौसीआईआई वास्तव में, यह * कर सकते हैं *। मैंने वास्तव में यह मेरे जवाब में दिखाया है। – justin

उत्तर

13

आप वस्तुओं की एक वेक्टर है, तो आप क्या कर सकते हैं निम्नलिखित:

NSArray *myArray = [NSArray arrayWithObjects:&vector[0] count:vector.size()]; 

हालांकि, अपने वेक्टर आदिम प्रकार, इस तरह के NSInteger, int, float, आदि के रूप में, आप के लिए होता है करने के लिए होता है, तो मैन्युअल रूप से वेक्टर में मानों को लूप करें और उन्हें पहले NSNumber में परिवर्तित करें।

+0

वेक्टर की वस्तुओं के जीवनकाल के संबंध में इस दृष्टिकोण से बहुत सावधान रहें! – Richard

+0

यह मेरे प्रश्न का उत्तर देता है। मेरे पास 'वेक्टर ' है इसलिए दुर्भाग्यवश मुझे सभी मानों के माध्यम से लूप करना होगा। – mydogisbox

+1

यह मेरे लिए काम नहीं करता है। मुझे "टाइप प्रकार के पैरामीटर को शुरू नहीं किया जा सकता है 'const __unsafe_unretained id *' प्रकार के रावल्यू के साथ ..." –

5

हाँ, आप बना सकते हैं निम्नलिखित दृष्टिकोण का उपयोग करके किसी NSInteger की NSArray एक std::vector<NSInteger> से रों:

// thrown together as a quick demo. this could be improved. 
NSArray * NSIntegerVectorToNSArrayOfNSIntegers(const std::vector<NSInteger>& vec) { 

    struct MONCallback { 
    static const void* retain(CFAllocatorRef allocator, const void* value) { 
     /* nothing to do */ 
     return value; 
    } 

    static void release(CFAllocatorRef allocator, const void* value) { 
     /* nothing to do */ 
    } 

    static CFStringRef copyDescription(const void* value) { 
     const NSInteger i(*(NSInteger*)&value); 
     return CFStringCreateWithFormat(0, 0, CFSTR("MON - %d"), i); 
    } 

    static Boolean equal(const void* value1, const void* value2) { 
     const NSInteger a(*(NSInteger*)&value1); 
     const NSInteger b(*(NSInteger*)&value2); 
     return a == b; 
    } 
    }; 

    const CFArrayCallBacks callbacks = { 
    .version = 0, 
    .retain = MONCallback::retain, 
    .release = MONCallback::release, 
    .copyDescription = MONCallback::copyDescription, 
    .equal = MONCallback::equal 
    }; 

    const void** p((const void**)&vec.front()); 
    NSArray * result((NSArray*)CFArrayCreate(0, p, vec.size(), &callbacks)); 
    return [result autorelease]; 
} 

void vec_demo() { 
    static_assert(sizeof(NSInteger) == sizeof(NSInteger*), "you can only use pointer-sized values in a CFArray"); 

    std::vector<NSInteger> vec; 
    for (NSInteger i(0); i < 117; ++i) { 
    vec.push_back(i); 
    } 
    CFShow(NSIntegerVectorToNSArrayOfNSIntegers(vec)); 
} 

हालांकि, अगर आप इस संग्रह के आपके उपयोग के संबंध बहुत सावधान होने की आवश्यकता होगी। फाउंडेशन उम्मीद करता है कि तत्व NSObject एस हो। यदि आप इसे बाहरी एपीआई में पास करते हैं जो NSObject एस की सरणी की अपेक्षा करता है, तो यह संभवतः एक त्रुटि का कारण बन जाएगा (EXC_BAD_ACCESSobjc_msgSend में)।

आमतौर पर, कोई उन्हें NSNumber में परिवर्तित कर देगा। मैं अपने प्रोग्राम में केवल NSArrayNSInteger एस का उपयोग करूंगा, केवल एक और एपीआई आवश्यक (ऐप्पल के पास कुछ हैं) - वे सिर्फ एक साथ बहुत अच्छी तरह से खेल नहीं सकते हैं।

+3

मैं वास्तव में 'NSNumber' का मतलब था लेकिन एक आकर्षक जवाब के लिए +1! – mydogisbox