iOS ARC - слабые и сильные свойства

Я пытаюсь понять, как работает ARC, и, насколько я знаю, я должен здесь что-то делать не так. Это код, который я использую:

Интерфейс:

@interface ViewController : UIViewController{

}

@property (strong, nonatomic) NSString * myString ; 
@property (weak, nonatomic) NSString * myPointer ;

Реализация:

 - (void)viewDidLoad{

     [super viewDidLoad];
     self.myString = @"Hello world!" ; // myString is strong
     self.myPointer = self.myString ; // myPointer var is weak

     [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
     [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

 - (void) makeNilMyValue{
     self.myString = nil ; 
}

 - (void) printValues{
     NSLog(@"myString: %@", self.myString) ;
     NSLog(@"myPointer: %@", self.myPointer) ; 
 }

После выполнения этого я получаю:

2012-02-26 11:40:41.652 test1[933:207] myString: (null)

2012-02-26 11:40:41.653 test1[933:207] myPointer: Hello world!

Если я не ошибаюсь, из-за слабости myPointer он не должен сохранять содержимое объекта. Таким образом, он должен показывать ноль вместо "Hello World!".

Что я делаю неправильно?

Следуя ответу Калеба, я создал еще один слабый указатель, см. Код ниже:

- (void)viewDidLoad{
    [super viewDidLoad];
    self.myString = @"Hello world!" ; // myString is strong
    self.myPointer = self.myString ; // myPointer var is weak
    self.myPointer2 = self.myString ; // myPointer2 var is weak

    [self performSelector:@selector(makeNilMyValue) withObject:nil afterDelay:1];    
    [self performSelector:@selector(printValues) withObject:nil afterDelay:2];    
}

- (void) makeNilMyValue{
    self.myPointer2 = @"value changed!" ;
    self.myString = nil ;

}

- (void) printValues{
    NSLog(@"myString: %@", self.myString) ;
    NSLog(@"myPointer: %@", self.myPointer) ;
}

Дело в том, что я все еще получил тот же ответ, что и раньше:

2012-02-26 12:08:13.426 test1[1333:207] myString: (null)
2012-02-26 12:08:13.427 test1[1333:207] myPointer: Hello world!

2 ответа

Решение

Как отметил Калеб, использование константы NSString для этого примера не очень хорошая идея.

Самый простой способ создать строковый объект в исходном коде - использовать конструкцию Objective-C @"...":

NSString * temp = @ "/ tmp / scratch"; Обратите внимание, что при создании строковой константы таким способом вы должны избегать использования чего-либо, кроме 7-битных символов ASCII. Такой объект создается во время компиляции и существует во время выполнения вашей программы. Компилятор делает такие объектные константы уникальными для каждого модуля, и они никогда не освобождаются, хотя вы можете сохранить и освободить их, как и любой другой объект. Вы также можете отправлять сообщения непосредственно на строковую константу, как и на любую другую строку:

BOOL same = [@ "сравнение" isEqualToString:myString];

Документация объясняет, что постоянные строки никогда не исчезнут.

Попробуйте использовать что-то еще для своего эксперимента. Я попробовал NSObject, и он дал ожидаемые результаты.

Интерфейс:

@interface ViewController : UIViewController

@property (strong, nonatomic) NSObject * myString; 
@property (weak, nonatomic) NSObject * myPointer;

@end

Реализация:

@implementation ViewController

@synthesize myString = _myString;
@synthesize myPointer = _myPointer;

- (void)viewDidLoad{

    [super viewDidLoad];

    self.myString = [[NSObject alloc] init];
    self.myPointer = self.myString;
    self.myString = nil; 
    NSLog(@"myString: %@", self.myString);
    NSLog(@"myPointer: %@", self.myPointer);
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

@end

Слабые указатели устанавливаются в ноль, когда нет сильных указателей на память, как объяснено в документации - Apple Developer или llvm.

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

Таким образом, он должен показывать ноль вместо "Hello World!".

Константные строки никогда не освобождаются, поэтому ваш `@"Hello World!" никогда не уходит Вот почему ваши слабые ссылки никогда не равны нулю.

Другие вопросы по тегам