分配和弱引用

3
我想了解assign和weak之间的区别。因此,我运行了下面的代码:
@interface Test : NSObject

@property(nonatomic, strong) NSString *str;
@property(nonatomic, assign) NSString *assignString;
@property(nonatomic, weak)   NSString *weakString;

@end

@implementation Test

- (id)init
{
    self =[super init];
    if (self)
    {
        self.str = @"i'm test string";
        
        self.assignString = self.str;
        self.weakString = self.str;

        self.str = nil;
        
        NSLog(@"dealloc \nstr = %p\n assignstr = %p\n weakStr = %p\n", self.str, self.assignString, self.weakString);

        NSLog(@"str = %@ \nassignStr = %@\n weakString = %@\n", self.str, self.assignString, self.weakString);
    }
    
    return self;
}

@end

我认为输出应该是这样的:
str = 0x0 assignString = 0x0 weakString = 0x0 str = (null) assignString = (null) weakString = (null)
但我得到了这个输出:
2015-06-17 11:22:04.676 AssignWeakDiff[4696:1897735] str = 0x0 assignstr = 0x100002078 weakStr = 0x100002078 str = (null) assignStr = i'm test string weakString = i'm test string
我的代码有什么问题吗?

2
尝试使用其他东西进行探索,而不是字面字符串,因为您无法控制它们的生命周期。 - CRD
一个简单的绕过字符串字面量的更改是 self.str = [@"hello" mutableCopy] - rob mayoff
1个回答

4
  1. 正如CRD所说,字符串具有各种优化来改变其内存管理。使用自己的自定义NSObject子类重复这个练习,你应该会看到传统的对象生命周期行为。

  2. assign属性的预期输出不正确。你应该预期它将指向已释放对象的悬挂指针。当对象被释放时,assign引用不会自动设置为nil。但是weak引用会自动设置为nil,而assign引用不会。

因此,如果你有以下属性:

@property (nonatomic, strong) MyObject *strongObj;
@property (nonatomic, assign) MyObject *assignObj;
@property (nonatomic, weak)   MyObject *weakObj;

然后执行:

self.strongObj = [[MyObject alloc] init];
self.assignObj = self.strongObj;
self.weakObj   = self.strongObj;

NSLog(@"%@ %@ %@", self.strongObj, self.assignObj, self.weakObj);

self.strongObj = nil;

NSLog(@"%@ %@ %@", self.strongObj, self.assignObj, self.weakObj);

在第二个 NSLog 语句中,strongweak 引用将会是 nil,但是 assign 引用不会。


谢谢你的回答,我也用NSArray重复了这个练习,控制台输出的结果和NSString相同。好的,我会用自定义类试一下。非常感谢你! - chengwen.Y
@chengwen.Y 顺便提一下,请确保使用alloc/init模式(不会创建autorelease对象),而不是方便的工厂方法。如果您使用数组并使用方便的方法进行实例化,则可能最终得到autorelease对象,该对象可能在池被排空之前不会被释放。 - Rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接