Objective-C:如何在GNUStep中启用ARC



Objective-C/ARC/内存管理问题已经在SO上完成,但这个问题似乎与现有的问题略有不同。

我一直在尝试将Objective-C与GNUStep和Clang一起使用。我已经下载了库显然是现代Objective-C功能(如ARC)所必需的;块工作,编译器接受@autoreleasepool以及关联的编译器标志。AppKit GUI 工具包可以工作,队列调度程序也可以工作。

我的理解,如果正确的话,是alloc ed对象会自动设置为在退出"父"堆栈帧的@autoreleasepool时释放,并且释放会减少引用计数。然而,编译器并不抱怨手动[super dealloc],并容忍手动autoreleasesreleases,这意味着ARC甚至没有打开。

有人可能会认为谷歌搜索GNUStep ARC ~enable会产生一些我错过的编译器标志,但它没有。

下面是一些示例代码。它是一个围绕 C99 bool s 的多维数组的对象包装器,该数组在 initmalloc,在 deallocfree d,我收集这是 ARC 代码中为数不多的合法使用dealloc之一。请注意,deallocputs 不会在@autoreleasepool完成后调用,尽管其中只创建了一个引用。但是,手动releaseautorelease效果很好。

#import <stdbool.h>
#import <stdio.h>
#import <stdlib.h>
#import <Foundation/Foundation.h>
@interface Area : NSObject {
    bool *area;
    size_t width, height;
}
- (id) initWithWidth:(size_t)aWidth height:(size_t)aHeight;
- (void) dealloc;
- (void) display;
@end
@implementation Area
- (id) initWithWidth:(size_t)aWidth height:(size_t)aHeight {
    self = [super init];
    width = aWidth;
    height = aHeight;
    area = malloc((sizeof *area) * aWidth * aHeight);
    for (size_t y = 0; y < aHeight; ++y) {
        for (size_t x = 0; x < aWidth; ++x) {
            area[(aHeight * y) + (aWidth * x)] = true;
        }
    }
    return self;
}
- (void) dealloc {
    free(area);
    puts("DEALLOCATED");
}
- (void) display {
    for (size_t y = 0; y < height; ++y) {
        putchar('|');
        for (size_t x = 0; x < width; ++x) {
            putchar(area[(height * y) + (width * x)]
                    ? '#'
                    : ' ');
        }
        puts("|");
    }
}
@end
int main(void)
{
    @autoreleasepool {
        id area = [[Area alloc] initWithWidth:10 height:10];
        [area display];
    }
    return EXIT_SUCCESS;
}

我的编译脚本(一旦我工作,我将使用适当的生成文件):-

#!/bin/sh
INC_FLAG=`gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS`
LIB_FLAG=`gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES`
clang -o main main.m 
    -I $INC_FLAG 
    -L $LIB_FLAG 
    
    -fblocks 
    -fobj-arc 
    -fconstant-string-class=NSConstantString 
    -D_NATIVE_OBJC_EXCEPTIONS 
    
    -pthread 
    -lgnustep-base 
    -ldispatch 
    -lgnustep-gui 
    -lobjc

我一直假设应该为在@autoreleasepool中创建的对象推断autorelease

提前感谢!

解决方案:Josh Caswell 指出我的编译器标志fobj-arc应该fobjc-arc。鉴于Clang没有给出这个标志无效的指示,我会把这个答案留给其他人。

最新更新