0

谁能解释一下为什么 case1 和 case2 在非 ARC 的情况下会崩溃,而其他的则不会?

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];
4

1 回答 1

3

所有都是不正确的,因为最终都会被释放两次,但有些可能会巧合地没有崩溃。

alloc分配保留计数为 1 的对象。减少release保留计数 1。autorelease最终减少保留计数 1。这意味着所有对象都已过度释放。

但是正如@Chuck 提到的,一些实例是常量,在编译时创建并且从未发布过,因此release可以autorelease调用许多尖头而不会崩溃。

字符串常量是这种情况的一个实例,其中过度释放不会导致崩溃:
NSString *s = @"aa";
即使过度释放也可以,因为编译器足够聪明:
NSString *s = [NSString stringWithString:@"aa"];
但是你会从当前的 LLVM 编译器得到警告,使用stringWithString文字是多余的.

于 2013-11-13T02:45:12.720 回答