2014-10-18 3 views
1

블록의 C 배열을 동적으로 인스턴스화하고로드 한 다음 실행하여 도움이 될 수 있습니다.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의 필요성을 완전히 이해하지는 못했지만 컴파일러는 불만을 토로합니다. 속성에도 강한 지표가 있어야합니까?

하나 이상의 장소에서 [모프 사본]을 수행해야합니까?

내가 망쳐 놓은 것이 있습니까?

답변

2

강한 포인터 배열 malloc 수 없습니다.

강력한 포인터의 의미에 대해 생각해보십시오 : 선언 될 때 값은 nil로 초기화됩니다. 변수가 범위를 벗어나면 기존 값을 해제합니다. 따라서 컴파일러는이를 수행 할 수있는 강력한 포인터를 추적 할 수 있어야합니다. 알 수없는 길이의 강력한 포인터 배열이있는 경우 예를 들어 범위를 벗어날 때 컴파일러에서 얼마나 많은 포인터를 놓을 지 알 수 있습니까? 그것은 할 수 없다.

C++ 용어에서 강력한 참조는 "non-POD"유형입니다. 이들은 사소한 생성자와 소멸자가 있습니다. 따라서 malloc으로 할당 할 수 없습니다.

그것은 ARC 사양에 here 언급된다

는 관리 동작이 원시적 제로 비트 패턴이 포함되어 있음을 보장하지 않고 __strong 또는 __weak 개체에서 수행 경우 또는 정의되지 않은 동작은 이러한 객체의 저장소가 인 경우 객체가 먼저 할당되지 않고 해제되거나 다시 사용되는 경우 포인터입니다. 당신이 후마다 malloc 전화 당신이 그들을 사용하기 전에, 당신이 할당 된 모든 포인터의 메모리를 제로 보장 경우 즉

, 당신은 mallocfree을 사용할 수있는 유일한 방법입니다. free 전까지는 항상 배열의 각 강력한 포인터에 nil을 할당해야합니다.

그러나 Objective-C++에서는 new[] 및 을 사용하여 강력한 포인터 배열을 동적으로 할당 할 수 있습니다.

이러한 요구 사항은 새로운 또는 [] 새로운 이 삭제 그들을 파괴와 보존 가능한 개체 소유자 유형의 만드는 객체, [], 또는 의사 소멸자 표현 삭제 오브젝티브 C++에서 자동으로 따른다.

+0

그래서 해결책은'calloc'입니까? –

+0

@BryanChen :'calloc'이 작동해야합니다. (플러스는'free'ing 전에'nil'에 대한 설정 포인터를 추가하고, 코드에서 자유로운 곳을 표시하지 않습니다.) – newacct

+0

실제로 __weak에 대한 포인터를 설정하여이 작업을 수행 할 수있었습니다. 단순히 __weak으로 설정하고 메모리 관리를 직접 처리 할 수 ​​있습니까? 또한 registerMorph 메서드에 'copy'를 추가했지만 그 밖에는 없습니다. 이 조합은 이제 제대로 작동하는 것 같습니다. 그러나, 나는 실제로 실제로 일어나고있는 것에 대해 꽤 불안하다. – aepryus