必须有一种更简单的方法来处理数组!

Eri*_*sen 5 iphone optimization objective-c

为了优化瓶颈,我将大型NSArray的创建转换为c风格的数组.(由此产生的创作是原始NSArray版本的1/8.是的!)但是一旦它被创建,速度不再是一个问题,所以我宁愿再次受益于它是一个NSArray.

然而,将c风格的数组转换为NSArray似乎是荒谬的(除非我缺少一些神奇的initWithArrayWrapElementsInObjects方法.)

正如我现在理解的那样,我首先必须创建一个NSMutableArray,迭代通过c样式数组将每个元素(在我的情况下浮动)转换为对象,将每个对象添加到NSMutableArray,然后使用NSMutableArray创建NSArray.

是对的吗?必须有一个更好的方法.

并且将不胜感激.

谢谢!

Ben*_*tto 7

没有直接的方法来获取你拥有的blob内存并将其廉价地"转换"为NSArray--毕竟,框架需要拥有那个内存,并且它不知道你从哪里得到它(malloc) ,堆栈等).如果initWithArrayWrapElementsInObjects有一个方便的方法,那么它本身就需要在内部进行你所猜测的内容:迭代你提供的内存并向其自身添加项目(可能框架可以像memcpy那样快速完成,但谁知道).

解决这个问题的一种方法(可能是一个有趣的学习练习)是通过实际创建自己的NSArray子类来完全按照自己的意愿管理内存(即,允许您使用您想要的任何语义创建和初始化),但这表现为作为NSArray的外部世界会.您可以通过继承NSArray并实现这些方法count:并对objectAtIndex:您要保留的任何内存进行操作来实现此目的.显然,您还需要在init/dealloc等方法中实现对自己内存的管理.请参阅此页面http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html"Subclassing Notes".

这里的设计讨论取决于您的数据是什么样的.当然,NSArray期望它的项目是Obj-C引用(类型id),而不仅仅是任意数据块.如果你的C风格数组持有结构或其他一些非对象引用的原始值,那么这种技术对你来说并不适用 - NSArray的界面永远不会满足于非引用项.

最后一点说明:你提到了一个N​​SMutableArray并用它"创建"一个NSArray.您应该知道NSMutableArray已经是NSArray,因为它是一个子类.您可以在任何想要NSArray的地方使用NSMutableArray的实例,而无需创建它的新副本.

更新:错过了包含浮点数的数组的注释.是的,你有点搞砸了.NSArrays想要对象.如果容量加倍是昂贵的部分(如另一张海报所述),那么尝试initWithCapacity:.如果它是浮动到对象类型的装箱/拆箱,那么你无能为力.

我已创建(但没有方便)一对非常简单的类(称为MYArray和MYMutableArray),这些类旨在用类似NSArray的方法包装这类数据.但它们不能与NSArrays互换.你必须故意使用它们.

更新#2.我知道这个问题已经存在很久了,但我只是重新审视它并意识到在这个特定情况下实际上有一种巧妙的方法.(你想要一个NSArray来自C风格浮点数组的非变量).您可以创建NSArray的自定义子类,它包装浮点值,只有在通过基元访问它们时才将它们转换为对象.这可能会在某些角落出现性能缺陷(?),但它确实可以满足您的要求:

@interface FloatProxyArray : NSArray
{
    float * values;
    NSUInteger count;
}
- (id)initWithCArray:(float *)arrayOfFloats count:(int)numberOfValues;
@end
Run Code Online (Sandbox Code Playgroud)

.

@implementation FloatProxyArray
- (id)initWithCArray:(float *)arrayOfFloats count:(int)numberOfValues
{
    if ((self = [super init])) {
        values = (float *)malloc(numberOfValues * sizeof(float));
        if (!values) { 
            [self release]; return nil; 
        }
        memcpy(values, arrayOfFloats, numberOfValues * sizeof(float));
        count = numberOfValues;
    }
    return self;
}

- (void)dealloc
{
    free(values);
    [super dealloc]
}

- (NSUInteger)count
{
    return count;
}

- (id)objectAtIndex:(NSUInteger)index
{
    if (index >= count) {
        [NSException raise:NSRangeException format:@""];
        return nil;
    }

    float val = values[index];
    return [NSNumber numberWithFloat:val];
}
@end
Run Code Online (Sandbox Code Playgroud)

(NB在编辑器中编写而没有编译/测试.)