Либо мой отладчик сломан, либо есть что-то фундаментальное, что я не понимаю.Простой Objective-C перевыпуск, который * должен * сбой не сбой. Зачем?
У меня есть очень простой код в очень простой командной строке программы, которая должна быть должна аварии. Однако это не сбой.
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. Может ли это иметь к этому какое-то отношение?
Я уже давно задавался вопросом об этом, видел ту же «проблему»/поведение. Надеюсь, кто-то может это объяснить. – Rits
Сбор мусора не мгновенен? :) – willcodejavaforfood
Дело не в этом. В среде сбора мусора явный вызов 'release' абсолютно ничего не делает. – Yuji