代码之家  ›  专栏  ›  技术社区  ›  Justin Meiners

Objective C-如何动态地向数组添加/删除结构

  •  1
  • Justin Meiners  · 技术社区  · 14 年前

    我需要能够添加和删除任意数量的点到一个数组。在C++中,我可以很容易地使用 vector 它允许我添加和删除任何类型的项。

    我知道我可以使用NSValue类将结构存储在NSMutableArray中,但是我更喜欢一种比不断创建和销毁NSValue对象更快的方法。有类似的东西吗 矢量 ObjuleC中的类还是有另一种方法来添加和移除我的结构到数组(我宁愿不使用ObjultC++)?或者我被NSMutableArray和NSValue困住了。

    编辑 :NSMutableData似乎是一种可能的解决方案。

    4 回复  |  直到 9 年前
        1
  •  2
  •   Aidan Steele    14 年前

    如果你不是针对iOS,我建议 NSPointerArray ,从而避免了包装生料的必要性 struct 数据类型 NSValue 容器。但是,这个类(不幸的是)在iOS上不可用。

    苹果承认这一点 NSArray documentation 对于iOS,在标题下 子类化的替代方法 .

    在创建NSArray的自定义类之前,请调查nspointerray和相应的核心基础类型CFArray引用。由于NSArray和CFArray是免费桥接的,因此可以用CFArray对象替换代码中的NSArray对象(使用适当的转换)。尽管它们是对应的类型,但CFArray和NSArray没有相同的接口或实现,有时可以使用CFArray来完成NSArray无法轻松完成的任务。例如,CFArray提供了一组回调,其中一些回调用于实现自定义的retain释放行为。如果为这些回调指定空实现,则可以轻松获得非保留数组。

    换句话说,您可以间接地创建 不可变数组 (或可变对应项)直接保存非对象数据类型的。

        2
  •  5
  •   Russell Zornes    14 年前

    NSArray/NSValue是在NSArray中存储CGPoints等内容的传统方式。你怎么知道它会太慢,除非你测量它?

        3
  •  1
  •   Sam    14 年前

    你总是可以在直上C中创建自己的向量类。下面是一个简单堆栈(可能更恰当地称为点堆栈)的例子,我将其作为概念的证明。制作LinkedLists之类的东西也不会太难。

    编辑:我看到其他的解决方案可能更好,因为它们不会强迫你重新发明轮子 .

    struct PointVector {
     CGPoint *data;
     int numItems;
     int maxSize;
    };
    
    void resize(struct PointVector *v, int newSize);
    void pushPoint(struct PointVector *v, CGPoint newPoint);
    void popPoint(struct PointVector *v);
    
    void init(struct PointVector *v) {
     v->data = NULL;
     v->numItems = 0;
     v->maxSize = 0;
    }
    
    void pushPoint(struct PointVector *v, CGPoint newPoint) {
     if (v->numItems + 1 > v->maxSize)
      resize(v, (v->maxSize ? v->maxSize * 2 : 1));
    
     v->data[v->numItems++] = newPoint;
    }
    
    void popPoint(struct PointVector *v) {
     if (v->numItems)
      v->numItems--;
    
    }
    
    void resize(struct PointVector *v, int newSize) {
     CGPoint *newData = calloc(sizeof(CGPoint), newSize);
    
     for (int i = 0; i < v->numItems; i++)
      newData[i] = v->data[i];
    
     if (v->data != NULL)
      free(v->data);
    
     v->data = newData;
     v->maxSize = newSize;
    }
    
        4
  •  0
  •   Albert Wang    14 年前

    如果这是一个选项,你可以混合使用C++和ObjuleC,在C++中编写核心算法,然后将.m文件重命名为.mm,其中包含并使用C++代码。