iOS ARC - слабые и сильные свойства - PullRequest
5 голосов
/ 26 февраля 2012

Я пытаюсь понять, как работает 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 ]

8 голосов
/ 26 февраля 2012

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

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

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 .

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

5 голосов
/ 26 февраля 2012

Таким образом, вместо «Hello World!» Должно отображаться nil.

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

...