【问题标题】:Objective-C: How is ARC Enabled Within GNUStep?Objective-C:如何在 GNUStep 中启用 ARC?
【发布时间】:2013-11-22 15:07:51
【问题描述】:

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

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

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

人们可能会想象谷歌搜索 GNUStep ARC ~enable 会产生一些我错过的编译器标志,但事实并非如此。

这是一些示例代码。它是一个围绕 C99 bools 的多维数组的对象包装器,它是init 中的malloced 和dealloc 中的freed,我认为这是dealloc 的少数合法用途之一在 ARC 代码中。请注意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;
}

我的编译脚本(一旦我完成了这个工作,我将使用适当的 makefile):-

#!/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

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

提前致谢!

【问题讨论】:

  • -fobj-arc 是这里的错字还是在您的实际脚本中?
  • 不,它在脚本中。我认为如果它的参数无效,编译器会抱怨......
  • 对我来说似乎是一个合理的假设,但绝对应该是@​​987654343@
  • 啊哈!我现在完全可以工作了。我很惊讶我可以将无效的废话作为参数传递给clang,它只是默默地忽略它们而不是警告我。现在它已启用,它抱怨手动 alloc。我还必须通过标志启用“非易碎 ABI”。谢谢您的帮助;在 cmets 部分解决了...我现在没有答案可以接受。
  • 很高兴你把它整理出来!如果其他人做同样的事情,我似乎不太可能特别发现这个问题。我建议只是将它发送到比特桶,但如果你愿意,你可以自己回答。

标签: objective-c memory-management automatic-ref-counting autorelease gnustep


【解决方案1】:

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

【讨论】:

  • 基于 LLVM 3.5.0 的 Debian clang 版本 3.5.0-10 确实表明 -fobj-arc 无效:它抛出错误,而 -fobjc-arc 被接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
相关资源
最近更新 更多