Назначить и Слабый

Я хочу посмотреть разницу между 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

Я думаю, что это должно выводить так:

ул = 0x0

присваиватьСтрока = 0x0

слабая строка = 0x0

ул = (нуль)

assignString = (нуль)

слабая строка = (нуль)

Но я получаю этот вывод:

2015-06-17 11:22:04.676 AssignWeakDiff[4696:1897735]

ул = 0x0

assignstr = 0x100002078

слабая строка = 0x100002078

ул = (нуль)

assignStr = я тестовая строка

weakString = я тестовая строка

Что-то не так с моим кодом?


person chengwen.Y    schedule 17.06.2015    source источник
comment
Попробуйте изучить что-то другое, кроме буквальных строк, вы не можете контролировать их время жизни.   -  person CRD    schedule 17.06.2015
comment
Простое изменение для обхода строкового литерала — self.str = [@"hello" mutableCopy].   -  person rob mayoff    schedule 17.06.2015


Ответы (1)


  1. Как сказал CRD, строки имеют всевозможные оптимизации, которые изменяют их управление памятью. Повторите это упражнение со своим собственным подклассом NSObject, и вы должны увидеть традиционное поведение объектов в течение жизненного цикла.

  2. Ожидаемый результат для свойства assign неверен. Вы должны ожидать, что это будет иметь висячий указатель на освобожденный объект. Ссылка assign не устанавливается на nil автоматически при освобождении объекта. Ссылка weak будет, а ссылка 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 ссылки strong и weak будут nil, а ссылка assign — нет.

person Rob    schedule 17.06.2015
comment
Спасибо за ваш ответ, я также повторяю это упражнение с NSArray, и консоль выводит тот же результат, что и NSString. Хорошо, я попробую это со своим пользовательским классом. большое спасибо!! - person chengwen.Y; 17.06.2015
comment
@chengwen.Y Кстати, убедитесь, что вы используете шаблон alloc/init (который не создаст объект autorelease), а не удобные фабричные методы. Если вы использовали массив и создали его экземпляр с помощью удобного метода, вы могли бы получить объект autorelease, который не может быть освобожден до тех пор, пока пул не будет слит. - person Rob; 17.06.2015