2016-12-22 1 views
6

Я знаю, что сильные и слабые модификаторы используются в объявлениях свойств, в то время как __strong и __weak используются в объявлениях переменных экземпляра ... strong говорит, что держать объект в памяти дольше как им владеют, и слабый говорит, что держать объект в памяти, пока кто-то еще имеет сильную ссылку на него ... правильно? но я не понимаю, почему слабый для свойства и __weak, например, переменная ведет себя по-другому? Вот что я задавался вопросом ...почему слабый для свойства и __weak, например, переменная ведет себя по-разному

@interface DemoViewController(){ 

    __weak NSArray *weakArray; 
    __strong NSArray *strongArray; 
    __weak NSString *weakString; 
    __strong NSString *strongString; 
} 

@property (weak) NSString *weakStringProperty; 
@property (strong) NSString *strongStringProperty; 

@property (weak) NSArray *weakArrayProperty; 
@property (strong) NSArray *strongArrayProperty; 

@end 

@implementation DemoViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    strongArray = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; 
    weakArray = strongArray; 

    NSLog(@"Round:1 strongArray is %@.", strongArray); 
    NSLog(@"Round:1 weakArray is %@.", weakArray); 

    strongArray = nil; 

    NSLog(@"Round:2 strongArray is %@.", strongArray); 
    NSLog(@"Round:2 weakArray is %@.", weakArray); 

    self.strongArrayProperty = [[NSArray alloc] initWithObjects:@"one",@"two", nil]; 
    self.weakArrayProperty = self.strongArrayProperty; 

    NSLog(@"Round:1 strongArrayProperty is %@.", self.strongArrayProperty); 
    NSLog(@"Round:1 weakArrayProperty is %@.", self.weakArrayProperty); 

    self.strongArrayProperty = nil; 

    NSLog(@"Round:2 strongArrayProperty is %@.", self.strongArrayProperty); 
    NSLog(@"Round:2 weakArrayProperty is %@.", self.weakArrayProperty); 


    strongString = [[NSString alloc]initWithFormat:@"instanceVariable"]; 
    weakString = strongString; 

    NSLog(@"Round:1 strongString is %@.", strongString); 
    NSLog(@"Round:1 weakString is %@.", weakString); 

    strongString = nil; 

    NSLog(@"Round:2 strongString is %@.", strongString); 
    NSLog(@"Round:2 weakString is %@.", weakString); 

    self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property"]; 
    self.weakStringProperty = self.strongStringProperty; 

    NSLog(@"Round:1 strongStringProperty is %@.", self.strongStringProperty); 
    NSLog(@"Round:1 weakStringProperty is %@.", self.weakStringProperty); 

    self.strongStringProperty = nil; 

    NSLog(@"Round:2 strongStringProperty is %@.", self.strongStringProperty); 
    NSLog(@"Round:2 weakStringProperty is %@.", self.weakStringProperty); 

} 
@end 

И вот приведенные журналы

Round:1 strongArray is (
    one, 
    two 
). 
Round:1 weakArray is (
    one, 
    two 
). 
Round:2 strongArray is (null). 
Round:2 weakArray is (null). 


Round:1 strongArrayProperty is (
    one, 
    two 
). 
Round:1 weakArrayProperty is (
    one, 
    two 
). 
Round:2 strongArrayProperty is (null). 
Round:2 weakArrayProperty is (
    one, 
    two 
).   —??? 

Round:1 strongString is instanceVariable. 
Round:1 weakString is instanceVariable. 
Round:2 strongString is (null). 
Round:2 weakString is (null). 


Round:1 strongStringProperty is Property. 
Round:1 weakStringProperty is Property. 
Round:2 strongStringProperty is (null). 
Round:2 weakStringProperty is Property. ——?? 

Оба слабые переменные экземпляра печати (нуль) после объектов они были слабо со ссылкой, устанавливаются в ноль и это как и ожидалось, но им интересно, почему и слабые свойства weakStringProperty и weakArrayProperty все еще печатают свои предыдущие значения и ведут себя так, как будто они явно указывают на strongStringProperty и strongArrayProperty соответственно?

Спасибо :)

+0

Я могу получить strongArrayProperty и weakArrayProperty как (null) в раунде 2. Хотя, weakStringProperty в раунде 2 по-прежнему «Свойство». Это очень странно, поскольку ARC должна технически справиться с этим. PS-Я запустил это на своем компьютере. –

+0

Я думаю, причина в том, что слабое свойство сохраняется, так как основной метод имеет пул автозапуска, который включает приложение. Из-за пула авторефератов слабое свойство сразу не устанавливается на нуль. Хотя, я попытался получить доступ к нему в viewDidAppear и didReceiveMemoryWarning (путем моделирования предупреждения о памяти), он все равно не стал ник. –

+0

странно !! когда я запускаю этот код на реальном устройстве, он дал ожидаемые результаты как для слабых переменных экземпляра, так и для слабых свойств ... это означает, что проблема связана только с симуляторами.Anyways Thxs @Kunal Shrivastava – Dipika

ответ

1

weakStringProperty не nil, потому что фонд по-прежнему сохраняя его.

Когда вы позвонили [[NSString alloc]initWithFormat:@"Property"], Фонд решил ставить строку как NSTaggedPointerString, которую она затем сохранила для будущего использования. Вы можете проверить это, войдя в класс:

NSLog(@"kindof: %@", [self.weakStringProperty class]); 

Я не уверен, что все критерии, которые система использует, чтобы решить, чтобы создать эти строки, но длина и изменяемости являются факторами. Любой из следующих вариантов получит желаемый результат.

// Longer string 
self.strongStringProperty = [[NSString alloc]initWithFormat:@"Property la la la"]; 

// Mutable string 
self.strongStringProperty = [[NSMutableString alloc]initWithFormat:@"Property"]; 
1

Ваши свойства являются атомарными, потому что вы не объявили их неатомичными. Атомные свойства возвращают объект, который сохраняется и автореализован, поэтому объект останется в пуле автозапуска и останется неизменным до тех пор, пока вы не выйдете из метода viewDidLoad.

Изменение, например,

@property (weak, nonatomic, readwrite) NSString *weakStringProperty; 

и вы, скорее всего, чтобы получить ожидаемый результат. Или проверьте свойства в другом методе позже, и слабые свойства, вероятно, будут равны нулю.

Однако iOS нередко создает объекты, которые никогда не будут выпущены. Например, есть один пустой объект NSArray, который никогда не будет выпущен. То же самое для многих объектов NSNumber, коротких строк, @YES и @NO и других. Нет гарантии, что объект будет освобожден, если вы считаете, что это будет, и, следовательно, не гарантирует, что слабый объект станет нулевым.

+0

на симуляторе ... Я пробовал с изменениями, которые вы сказали сделать, и как результаты ... свойства все еще не были установлены на nil в viewDidLoad и viewWillAppear, но они были установлены в nil в viewDid Appear. Но странно то, что когда я запускаю это на устройстве, все слабые свойства устанавливаются в нуль после того, как объекты, на которые они указывают, установлены на нуль и регистрируют ожидаемые результаты. В любом случае thxs :) – Dipika

Смежные вопросы