5

我写了下面的示例代码来看看 ARC 是如何工作的

@property (nonatomic, weak) NSString *myString;
@property (nonatomic, weak) NSObject *myObj;
@end

@implementation ViewController
@synthesize myString = _myString;
@synthesize myObj = _myObj;
- (void) viewDidAppear:(BOOL)animated
{
    NSLog(@"Appearing Obj: !%@!",self.myObj);
    NSLog(@"Appearing String: !%@!",self.myString);
}

- (void)viewDidLoad
{
    self.myObj = [[NSObject alloc] init];
    self.myString = [[NSString alloc] init];
    NSLog(@"Loading Obj %@",self.myObj);
    NSLog(@"Loading String: !%@!",self.myString);
}

然而令人惊讶的是,我得到了这些结果:

2012-06-19 15:08:22.516 TESTER[4041:f803] Loading Obj (null)
2012-06-19 15:08:22.517 TESTER[4041:f803] Loading String: !!
2012-06-19 15:08:22.533 TESTER[4041:f803] Appearing Obj: !(null)!
2012-06-19 15:08:22.535 TESTER[4041:f803] Appearing String: !!

如您所见,Obj 已正确释放,但我的字符串(这也是一个弱属性)没有打印出 null...为什么不呢?

4

2 回答 2

12

NSString使用各种内部技巧来重用对象并避免不必要的分配和复制。它可以做到这一点,因为NSString实例是不可变的。在这种情况下,可能有一个共享实例来表示一个由 正在返回的空字符串[[NSString alloc] init],并且这个共享实例将作为单例保留在其他地方。

于 2012-06-19T20:12:43.237 回答
6

[[NSString alloc] init]总是返回相同的值。您可以自行检查。

NSString *string1 = [[NSString alloc] init];
NSString *string2 = [[NSString alloc] init];
NSString *string3 = [[NSString alloc] init];
NSLog(@"string1 = %p, string2 = %p, string3 = %p", string1, string2, string3)

此代码返回三个相同的地址。就我而言,输出是:

string1 = 0x3e8dd74c, string2 = 0x3e8dd74c, string3 = 0x3e8dd74c

这意味着[[NSString alloc] init]返回Singleton。单身人士通常不能被释放。

使用其他方法(如 )创建字符串initWithFormat:会生成通常的“非单例”对象,通常可以释放,但有一些例外。

进一步: 查看源代码(汇编程序):

-[NSPlaceholderString init]:
00040ea4        f64b009c        movw    r0, 0xb89c
00040ea8        f2c00016        movt    r0, 0x16
00040eac            4478        add     r0, pc
00040eae            4770        bx      lr

它会是这样的(在objectiveC中)

-(id)init
{
    return SOME_CONSTANT_VALUE;
}

可能是kCFEmptyString,但我不确定。

于 2012-06-19T21:35:42.377 回答