Objective-C/ARC/内存管理问题已经在SO上完成,但这个问题似乎与现有的问题略有不同。
我一直在尝试将Objective-C与GNUStep和Clang一起使用。我已经下载了库显然是现代Objective-C功能(如ARC)所必需的;块工作,编译器接受@autoreleasepool
以及关联的编译器标志。AppKit GUI 工具包可以工作,队列调度程序也可以工作。
我的理解,如果正确的话,是alloc
ed对象会自动设置为在退出"父"堆栈帧的@autoreleasepool
时释放,并且释放会减少引用计数。然而,编译器并不抱怨手动[super dealloc]
,并容忍手动autoreleases
和releases
,这意味着ARC甚至没有打开。
有人可能会认为谷歌搜索GNUStep ARC ~enable
会产生一些我错过的编译器标志,但它没有。
下面是一些示例代码。它是一个围绕 C99 bool
s 的多维数组的对象包装器,该数组在 init
中malloc
,在 dealloc
中free
d,我收集这是 ARC 代码中为数不多的合法使用dealloc
之一。请注意,dealloc
的 puts
不会在@autoreleasepool完成后调用,尽管其中只创建了一个引用。但是,手动release
或autorelease
效果很好。
#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没有给出这个标志无效的指示,我会把这个答案留给其他人。