IOS о слабых и сильных, каков должен быть результат? и постоянная декларация
Есть два свойства, как показано ниже
#import <Foundation/Foundation.h>
@interface Contact : NSObject
@property(nonatomic, strong)NSDate *birthDay;
@property(nonatomic, weak)NSDate *birthDay1;
- (void)testWeakProperty;
@end
в файле реализации как:
- (void)testWeakProperty {
self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
}
почему результат не _birthday1
является (null), (null)
?
Я обнаружил, что iOS ARC - слабые и сильные свойства. если self.birthDay
постоянно, оно не будет освобождено. но есть [NSDate dateWithTimeIntervalSinceNow:0]
,
Теперь я хочу знать, является ли возвращаемое значение константой и как проверить, объявить ли результат константой и переменной.
2 ответа
Ключевым моментом здесь является то, что вы имеете дело с объектом автоматического выпуска. Если имя метода начинается с init
, copy
, mutableCopy
или же new
, вы получите объект без авто-релиза. Это не тот случай здесь (вы используете dateWithTimeIntervalSinceNow
) и в результате вы получите объект автоматического выпуска.
Таким образом, вы создаете экземпляр объекта autorelease, и, следовательно, он не будет освобожден до тех пор, пока пул autorelease не будет удален. И твоей слабой ссылки не будет nil
-ед, пока объект не будет освобожден. Освобождение объектов автоматического выпуска происходит, когда ваше приложение возвращается к циклу выполнения (или вы явно создаете свой собственный пул автоматического выпуска).
Это не вопрос объекта, являющегося "константой". И этот другой вопрос, на который вы ссылаетесь, обсуждается NSString
который, будучи сильно оптимизирован, не соответствует традиционным правилам управления памятью объектов.
Вы можете изменить поведение, явно добавив свой собственный пул автоматического выпуска, что приведет к освобождению объекта, когда пул будет очищен в конце @autoreleasepool
блок, и вы увидите свой (null), (null)
ответ:
@autoreleasepool {
self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
}
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
Вы также можете использовать не-авто-релизный объект (например, использовать метод, имя которого начинается с init
) и этот объект без авто-выпуска будет освобожден сразу после установки в nil
:
self.birthDay = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
Это также покажет вам (null), (null)
,
Как объясняет Роб, важным моментом является тот факт, что вы используете автоматически выпущенный объект.
Просто небольшая точность в его объяснении, [NSDate date...]
на самом деле это короткая (удобная) версия:
[[[NSDate alloc] initWith...] autorelease]
Которые ведут себя иначе, чем неавторизованный экземпляр:
[[NSDate alloc] initWith...]