将块存储在c风格的数组中

时间:2014-10-18 01:23:45

标签: objective-c arrays objective-c-blocks

我正在尝试动态实例化一个c数组的块,加载它然后运行它们并可以使用一些帮助。

// Definitions ===========================================
typedef void (^MorphC)(ScratchC* scratch);

@property (nonatomic) MorphC __strong * morphCs;

// Building up the Morph Registry ========================
static NSMutableDictionary* morphs_;
+ (void) initialize {
    morphs_ = [[NSMutableDictionary alloc] init];
    [MathC hydrate];
}
+ (void) hydrate {  
    [MathC registerMorph:@"sin" execute:^(ScratchC* scratch) {
        AEScratchPush(scratch, sin(AEScratchPop(scratch)));
    }];
}
+ (void) registerMorph:(NSString*)name execute:(MorphC)execute {
    [morphs_ setObject:execute forKey:name];
}
+ (MorphC) morphFromKey:(NSString*)key {
    return [morphs_ objectForKey:key];
}


// Loading up a temporary NSMutableArray* _compiling =====
- (void) applyTag:(NSString*)tag stack:(Stack*)stack {
    [_compiling addObject:[MathC morphFromKey:tag]];
}

// Initializing C Array and loading from NSMutableArray ==
- (void) build {
    _morphCs = (MorphC __strong *)malloc(_compiling.count*sizeof(MorphC));
    i = 0;
    for (MorphC morph in _compiling)
        _morphCs[i++] = morph;              // Currently, getting a bad ACCESS here
}

// Executing the Morphs ==================================
- (CGFloat) evaluateFloat:(VarsC*)vars {
    if (![_morphs count]) return NAN;
    AEScratchLoadVariables(_scratch, vars);

    for (int i=0;i<[_morphs count];i++)
        _morphCs[i](_scratch);

    return AEScratchPop(_scratch);
}

我正在构建C阵列时获得EXC_BAD_ACCESS,但我怀疑我有很多问题。我不完全理解在morphCs定义中对__strong的需求,但是编译器没有抱怨。该物业是否也有强大的指标?

我是否需要在一个或多个地方进行[变形复制]?

还有什么我搞砸了吗?

1 个答案:

答案 0 :(得分:2)

你不能malloc一系列强指针。

考虑强指针的语义:当声明它时,它的值被初始化为nil。当变量超出范围时,它会释放其现有值。因此,编译器必须能够跟踪强指针以便能够执行此操作。如果你有一个未知长度的强指针数组,当它超出范围时,例如,编译器如何知道要释放多少指针?它不能。

在C ++术语中,强引用是“非POD”类型 - 它们具有非平凡的构造函数和析构函数。因此,无法使用malloc分配它们。

ARC规范中提到here

  

如果对a执行托管操作,则为未定义的行为   __strong或__weak对象,不保证它包含原始零位模式,或者此类对象的存储是   在没有首先为对象分配null的情况下释放或重用   指针。

换句话说,唯一可以使用mallocfree的方法是,如果你保证每次调用malloc之后你将所分配的所有指针的内存归零,在使用它们之前。每次free之前,您都要保证首先将nil分配给数组中的每个强指针。

但是,在Objective-C ++中,可以使用new[]delete[]来动态分配强指针数组。

  

这些要求在Objective-C ++中自动遵循   使用new或new []和创建可保留对象所有者类型的对象   使用delete,delete []或伪析构函数销毁它们   表达