Objective-C/ARC/内存管理问题已经在 SO 上完成了,但这似乎与现有问题略有不同。
我一直在尝试将 Objective-C 与 GNUStep 和 Clang 一起使用。我已经下载了像 ARC 这样的现代 Objective-C 特性显然需要的库;块 work 和@autoreleasepool
s 与相关的编译器标志一起被编译器接受。AppKit GUI 工具包可以工作,队列调度程序也是如此。
如果正确的话,我的理解是alloc
ed 对象会自动设置为在退出@autoreleasepool
“父”堆栈帧时释放,并且释放会减少引用计数。然而编译器并不哀叹手册[super dealloc]
并且容忍手册autoreleases
and releases
,这意味着 ARC 甚至没有打开。
有人可能会想象谷歌搜索GNUStep ARC ~enable
会产生一些我错过的编译器标志,但事实并非如此。
这是一些示例代码。bool
它是一个围绕 C99 s 的多维数组的对象包装器,它位于malloc
ed ininit
和free
d within中,我认为这是ARC 代码dealloc
中为数不多的合法用途之一。dealloc
请注意, @autoreleasepool 完成后不会dealloc
调用's ,尽管其中只创建了一个引用puts
。但是,手册或效果很好。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;
}
我的编译脚本(一旦我完成了这个工作,我将使用适当的 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
.
提前致谢!