简体   繁体   English

将std:vector转换为NSArray

[英]convert std:vector to NSArray

有没有一种很好的方法将vector<int32_t>转换为NSNumberNSArray ,或者循环并添加到NSMutableArray几乎是唯一的方法?

If you have a vector of objects, you can do the following: 如果您有对象矢量,则可以执行以下操作:

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

However, if your vector contains primitive types, such as NSInteger , int , float , etc., you would have to manually loop the values in the vector and convert them to a NSNumber first. 但是,如果向量包含基本类型,例如NSIntegerintfloat等,则必须手动循环向量中的值并首先将它们转换为NSNumber

Yes, you can create an NSArray of NSInteger s from a std::vector<NSInteger> by using the following approach: 是的,您可以使用以下方法从std::vector<NSInteger>创建NSIntegerNSArray

// 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));
}

However, you will need to be very cautious regarding your use of this collection. 但是,您对此系列的使用需要非常谨慎。 Foundation expects the elements to be NSObject s. Foundation希望这些元素是NSObject的。 If you pass it into an external API that expects an array of NSObject s, it will probably cause an error (read: EXC_BAD_ACCESS in objc_msgSend ). 如果将它传递给需要NSObject数组的外部API,则可能会导致错误(读取: EXC_BAD_ACCESS中的objc_msgSend )。

Usually, one would convert them to NSNumber . 通常,人们会将它们转换为NSNumber I would use this NSArray of NSInteger s in my program only if another another API needed it (Apple has a few) -- They just don't play very well together. 只有当另一个API 需要它时,我才会在我的程序中使用NSIntegerNSArray (Apple有一些) - 它们只是不能很好地结合在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM