源包含almostempty autoreleasepool。没有它,应用程序就像标准c。
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSLog(@"Hello, World!");
}
return 0;
}
请:
CC=clang
CXX=clang++
OPT_RELEASE=-O3
OPT_DEBUG=-DDEBUG -g
INCLUDE=-I.
LIBRARY= -L/usr/local/lib
CFLAGS=`gnustep-config --objc-flags` -fobjc-runtime=gnustep
LDFLAGS=`gnustep-config --base-libs` -fobjc-runtime=gnustep
SOURCES= hello.m
OBJECTS=$(SOURCES:.m=.o)
DEPENDENCIES=$(SOURCES:.m=.d)
EXECUTABLE=hello
all: $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LIBRARY) $(LDFLAGS) $(OBJECTS) $(STATICLIBS) -o $@
%.o: %.m
$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
clean:
rm -rf $(OBJECTS) $(EXECUTABLE) $(DEPENDENCIES) core
核心:
#0 0x0000000000000000 in ?? ()
#1 0x00007ffff71f5c06 in objc_autoreleasePoolPop () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#2 0x00007ffff7716753 in -[NSAutoreleasePool emptyPool] (self=0x77dd30, _cmd=0x7ffff7cf5010 <.objc_selector_list+128>) at NSAutoreleasePool.m:411
#3 0x00007ffff77168c4 in -[NSAutoreleasePool dealloc] (self=0x77dd30, _cmd=0x7ffff7cf4fa0 <.objc_selector_list+16>) at NSAutoreleasePool.m:729
#4 0x00007ffff771686c in -[NSAutoreleasePool release] (self=0x77dd30, _cmd=0x7ffff7cfc3c0 <.objc_selector_list+240>) at NSAutoreleasePool.m:722
#5 0x00007ffff7728ca9 in +[NSCalendarDate initialize] (self=0x7ffff7cfc1e0 <_OBJC_CLASS_NSCalendarDate>, _cmd=0x63b470) at NSCalendarDate.m:380
#6 0x00007ffff71e5e93 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#7 0x00007ffff71f3199 in objc_msg_lookup_sender () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#8 0x00007ffff71f2eb7 in slowMsgLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#9 0x00007ffff71f5048 in objc_msgSend_fpret () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#10 0x00007ffff776d4c6 in +[NSDate initialize] (self=0x7ffff7d0afe0 <_OBJC_CLASS_NSDate>, _cmd=0x63b470) at NSDate.m:134
#11 0x00007ffff71e5e93 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#12 0x00007ffff71f3199 in objc_msg_lookup_sender () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#13 0x00007ffff71f2eb7 in slowMsgLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#14 0x00007ffff71f5048 in objc_msgSend_fpret () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#15 0x00007ffff78cdb30 in +[NSUserDefaults initialize] (self=0x7ffff7d7b4a0 <_OBJC_CLASS_NSUserDefaults>, _cmd=0x63b470) at NSUserDefaults.m:563
#16 0x00007ffff71e5e93 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#17 0x00007ffff71f3199 in objc_msg_lookup_sender () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#18 0x00007ffff71f2eb7 in slowMsgLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#19 0x00007ffff71f5048 in objc_msgSend_fpret () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#20 0x00007ffff780c632 in +[NSObject initialize] (self=0x7ffff7d3c460 <_OBJC_CLASS_NSObject>, _cmd=0x63b470) at NSObject.m:1144
#21 0x00007ffff71e5e93 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#22 0x00007ffff71e5b06 in objc_send_initialize () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#23 0x00007ffff71f3199 in objc_msg_lookup_sender () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#24 0x00007ffff71f2eb7 in slowMsgLookup () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#25 0x00007ffff71f5048 in objc_msgSend_fpret () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#26 0x00007ffff71f58df in initAutorelease () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#27 0x00007ffff71f56ad in objc_autoreleasePoolPush () from /usr/GNUstep/Local/Library/Libraries/libobjc.so.4.6
#28 0x0000000000400a14 in main (argc=1, argv=0x7fffffffdbe8) at hello.m:5
答案 0 :(得分:1)
所以这是我的研究结果:
如果在NSAutoreleasePool.m中找不到有效的arc autorelease-pool,则在libobjc2(arc.m)中将DeleteAutoreleasePool声明为IMP,并从objc_autoreleasePoolPop调用。
使用clang的实际版本,NSAutoreleasePool正确检测发布池的可用性。 (在capabilities.h中声明)
这解释了为什么NSAutoreleasePool有效。
arc.m作为回报读取此结果。如果结果是肯定的,它什么也不做,否则它会调用NSAutoreleasePool中的引用计数方法(因此可以使用GCC和其他编译器)。
此过程中的缺陷可以在initAutorelease(arc.m)中找到。这里使用 class_respondsToSelector 检测自动释放池的可用性。换句话说,类方法用作feature-flag(叹气)。
验证方法定义如下:
#ifdef ARC_RUNTIME
...
/**
* Indicate to the runtime that we have an ARC-compatible implementation of
* NSAutoreleasePool and that it doesn't need to bother creating objects for
* pools.
*/
- (void)_ARCCompatibleAutoreleasePool {}
#else
此功能的问题是:
即使启用了调试,我也希望在编译期间忽略此函数,也不会将其作为库调用导出。
这就解释了为什么obj-arc(@autoreleasepool)不适用于clang 3.4 +。
如果你只对你的objc项目使用clang,你可以重写或简单地停用这个检测方法。