Objective c ios中的内存管理
有谁能解释一下,为什么案例1和案例2在非ARC情况下会崩溃,而其他案例则不会崩溃Objective c ios中的内存管理,objective-c,memory-management,Objective C,Memory Management,有谁能解释一下,为什么案例1和案例2在非ARC情况下会崩溃,而其他案例则不会崩溃 Case1: NSString *rr = [[NSString alloc] initWithString:@"AB"]; [rr release]; [rr autorelease]; Case2: NSString *rrr = [[NSString alloc] initWithString:@"AB"]; [rrr autorelease]; [rrr r
Case1:
NSString *rr = [[NSString alloc] initWithString:@"AB"];
[rr release];
[rr autorelease];
Case2:
NSString *rrr = [[NSString alloc] initWithString:@"AB"];
[rrr autorelease];
[rrr release];
Case3:
NSMutableString *rr1 = [[NSMutableString alloc] initWithString:@"AB"];
[rr1 release];
[rr1 autorelease];
Case4:
NSMutableString *rrr1 = [[NSMutableString alloc] initWithString:@"AB"];
[rrr1 autorelease];
[rrr1 release];
Case5:
NSArray *rr3 = [[NSArray alloc] initWithObjects:@"jj", nil];
[rr3 release];
[rr3 autorelease];
Case6:
NSArray *rrr3 = [[NSArray alloc] initWithObjects:@"jj", nil];
[rrr3 autorelease];
[rrr3 release];
Case7:
NSMutableArray *rr2 = [[NSMutableArray alloc] initWithObjects:@"jj", nil];
[rr2 release];
[rr2 autorelease];
Case8:
NSMutableArray *rr2 = [[NSMutableArray alloc] initWithObjects:@"jj", nil];
[rr2 autorelease];
[rr2 release];
所有这些都是不正确的,因为最终它们都将被释放两次,但有些可能碰巧不会崩溃
alloc
分配保留计数为1的对象<代码>释放减少保留计数1<代码>自动释放最终会减少保留计数1。这意味着所有人都被过度释放了
但正如@Chuck提到的,有些实例是常量,在编译时创建,从未发布过,因此可以对许多TINE调用release
和autorelease
,而不会崩溃
字符串常量是过度释放不会导致崩溃的一个实例:NSString*s=@“aa”代码>
即使过度发布,也没关系,因为编译器足够聪明:
NSString*s=[nsstringwithstring:@“aa”]代码>
但是您将从当前的LLVM编译器中得到一个警告,即使用带有文本的stringWithString
是多余的。所有都是不正确的,因为最终所有都将被释放两次,但有些可能恰好不会崩溃
alloc
分配保留计数为1的对象<代码>释放
减少保留计数1<代码>自动释放
最终会减少保留计数1。这意味着所有人都被过度释放了
但正如@Chuck提到的,有些实例是常量,在编译时创建,从未发布过,因此可以对许多TINE调用release
和autorelease
,而不会崩溃
字符串常量是过度释放不会导致崩溃的一个实例:NSString*s=@“aa”代码>
即使过度发布,也没关系,因为编译器足够聪明:
NSString*s=[nsstringwithstring:@“aa”]代码>
但是您将从当前的LLVM编译器中得到一个警告,即使用带有文本的stringWithString
是多余的。所有都是不正确的,因为最终所有都将被释放两次,但有些可能恰好不会崩溃
alloc
分配保留计数为1的对象<代码>释放
减少保留计数1<代码>自动释放
最终会减少保留计数1。这意味着所有人都被过度释放了
但正如@Chuck提到的,有些实例是常量,在编译时创建,从未发布过,因此可以对许多TINE调用release
和autorelease
,而不会崩溃
字符串常量是过度释放不会导致崩溃的一个实例:NSString*s=@“aa”代码>
即使过度发布,也没关系,因为编译器足够聪明:
NSString*s=[nsstringwithstring:@“aa”]代码>
但是您将从当前的LLVM编译器中得到一个警告,即使用带有文本的stringWithString
是多余的。所有都是不正确的,因为最终所有都将被释放两次,但有些可能恰好不会崩溃
alloc
分配保留计数为1的对象<代码>释放
减少保留计数1<代码>自动释放
最终会减少保留计数1。这意味着所有人都被过度释放了
但正如@Chuck提到的,有些实例是常量,在编译时创建,从未发布过,因此可以对许多TINE调用release
和autorelease
,而不会崩溃
字符串常量是过度释放不会导致崩溃的一个实例:NSString*s=@“aa”代码>
即使过度发布,也没关系,因为编译器足够聪明:
NSString*s=[nsstringwithstring:@“aa”]代码>
但是当前的LLVM编译器会警告您,将stringWithString
与文本一起使用是多余的。我认为您已经向后描述了这种情况。第一个和第二个不应该崩溃,而其他应该崩溃。不管怎样,我建议你读一读这本书。这份文件解释了一切,几乎可以肯定,它比在座的任何人都做得更好。如果您在阅读文档后对某些内容不清楚,可以询问一下-要求他人在堆栈溢出时为您重写文档对任何相关人员来说都不是一个好主意。@Zaph:因为除非苹果在我不看的时候翻转了脚本,否则不会创建或销毁常量字符串。当你保留或复制这些版本时,它们会忽略这些版本,只返回它们自己。@Chuck,是的,你是对的!我没有注意到,这些都不对。您应该释放
或自动释放
,但不能两者兼而有之。我不知道为什么一个人会关心为什么不正确地做一件事会导致崩溃,而不正确地做另一件事却不会。仅仅因为它没有崩溃并不意味着它是对的。当然,不要编写依赖于过度释放对象的代码,以确保在某些情况下不会崩溃。实际上,这是一个面试问题,我被问到了,我不确定它的正确答案是什么。所以,我想在这里问一下。所以,有人能证实我的正确答案以备将来参考吗?我想你已经把情况描述得倒过来了。第一个和第二个不应该崩溃,而其他应该崩溃。不管怎样,我建议你读一读这本书。这份文件解释了一切,几乎可以肯定,它比在座的任何人都做得更好。如果您在阅读文档后对某些内容不清楚,可以询问一下-要求他人在堆栈溢出时为您重写文档对任何相关人员来说都不是一个好主意。@Zaph:因为除非苹果在我不看的时候翻转了脚本,否则不会创建或销毁常量字符串。当你保留或复制这些版本时,它们会忽略这些版本,只返回它们自己。@Chuck,是的,你是对的!我没有注意到,这些都不对。你知道吗