Либо мой отладчик неисправен, либо есть нечто фундаментальное, чего я не понимаю.
У меня есть очень простой код в очень простой программе командной строки, который должен аварийно завершить работу. Тем не менее, это не сбой.
int main (int argc, const char * argv[])
{
NSString *string = [[NSString alloc] initWithString:@"Hello"];
[string release];
NSLog(@"Length: %d", [string length]);
return 0;
}
Оператор журнала печатает «Длина: 5», как и следовало ожидать для правильной строки. Однако строка должна быть освобождена этой точкой, и должна быть выдана ошибка exec_bad_access
.
Я пробовал этот код с подключенным отладчиком и без подключенного отладчика - оба дают одинаковый результат. Я также включил (и отключил) NSZombie
, что, похоже, не дает никакого эффекта (я изначально думал, что это проблема, поскольку NSZombie
объекты никогда не освобождаются - но он по-прежнему не падает при отключенном NSZombie
).
У меня установлены точки останова в локальном файле .gdbinit
для таких вещей, как -[NSException raise]
и objc_exception_throw
. У меня также есть точки останова во многих методах на NSZombie
, чтобы их перехватить.
fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
#define NSZombies
# this will give you help messages. Set to NO to turn them off.
set env MallocHelp=YES
# might also be set in launch arguments.
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1
set env CFZombie 5
fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]
fb szone_error
fb objc_exception_throw
С этими установленными точками останова и включенным NSZombie я должен напечатать что-то вроде [NSString length]: message sent to deallocated instance 0x100010d39
на консоли, но я этого не вижу. Я вижу NSLog
, печатающий длину как 5.
Я вижу похожее поведение с другими классами, такими как NSURL
и NSNumber
. Но некоторые классы аварийно завершаются, как, например, NSError
и NSObject
.
Это как-то связано с кластерами классов? Разве они не следуют тем же правилам в отношении управления памятью?
Если кластеры классов не связаны с этой проблемой, единственная другая общая черта, которую я мог видеть, состояла в том, что классы, которые не терпят крах таким образом, все бесплатно соединяются мостом с аналогом Core Foundation. Может ли это быть как-то связано с этим?