Различия между сильным и слабым в Objective-C


308

Я новичок в Obj-C, поэтому мой первый вопрос:

Каковы различия между strongи weakв @propertyобъявлениях указателей на объекты?

Кроме того, что это nonatomicзначит?


19
на самом деле это хорошие вопросы, иногда мы забыли, как основная концепция сильных / слабых и атомных / неатомных предпочтений .... :) Спасибо, что напомнили нам об этом ...
andikurnia

10
@JackyBoy Забавно, что предложенный простой поиск в Google привел меня сюда. #circularreference
Джейсон Ренальдо,

10
Я склонен не доверять многим ответам в Google, но всегда
обращаюсь

Ответы:


642

Сильная ссылка (которую вы будете использовать в большинстве случаев) означает, что вы хотите «владеть» объектом, на который вы ссылаетесь, с помощью этого свойства / переменной. Компилятор позаботится о том, чтобы любой объект, который вы назначаете этому свойству, не был уничтожен, пока вы на него указываете с сильной ссылкой. Только после того, как вы установите свойство в nil, объект будет уничтожен (если только один или несколько других объектов также не имеют строгой ссылки на него).

Напротив, со слабой ссылкой вы обозначаете, что не хотите контролировать время жизни объекта. Объект, на который вы слабо ссылаетесь, живет только потому, что по крайней мере еще один объект содержит сильную ссылку на него. Если это уже не так, объект уничтожается, и ваше слабое свойство автоматически устанавливается на nil. Наиболее частые случаи использования слабых ссылок в iOS:

  1. свойства делегата, на которые часто ссылаются слабо, чтобы избежать сохранения циклов, и

  2. подпредставления / элементы управления основного представления контроллера представления, потому что эти представления уже прочно удерживаются основным представлением.

Атомное и неатомное относится к безопасности потоков методов получения и установки, которые компилятор синтезирует для свойства. atomic (по умолчанию) указывает компилятору сделать методы доступа потоко-безопасными (добавляя блокировку до доступа к ivar), а nonatomic делает обратное. Преимущество nonatomic - немного более высокая производительность. На iOS Apple использует nonatomic почти для всех своих свойств, поэтому общий совет - сделать то же самое.


28
@Bourne: Это зависит от того, что вы подразумеваете под безопасностью потоков. atomicгарантирует, что свойство может быть безопасно прочитано и записано из нескольких потоков одновременно. Это не означает, что объект, все свойства которого являются atomicавтоматически потокобезопасным.
Оле Бегеманн

3
Великолепные детали. Я думаю, что я действительно не получил это до сих пор. Спасибо.
Ахмедалкафф

1
Согласно документации Apple, атомарные и неатомные должны быть синонимами безопасности потоков. developer.apple.com/library/ios/documentation/cocoa/conceptual/…
Муртаза Хуршид Хуссейн

5
«Примечание: атомарность свойства не является синонимом безопасности потока объекта». developer.apple.com/library/ios/documentation/cocoa/conceptual/...
GS

почему бы нам просто не удалить экземпляр, когда мы не хотим? Почему мы не можем просто вынуть воздух из воздушного шара или уничтожить его, когда мы не хотим, почему мы должны заботиться о прикрепленных струнах? Нам просто нужны данные.
Ашиш Писей

707

Может быть полезно подумать о сильных и слабых ссылках с точки зрения воздушных шаров.

Воздушный шар не улетит, пока хотя бы один человек держится за привязанную к нему веревку. Количество людей, удерживающих строки, является счетом удержания. Когда никто не держится за веревку, баллон улетит (dealloc). У многих людей могут быть струны к тому же воздушному шару. Вы можете получить / установить свойства и вызвать методы для ссылочного объекта с сильными и слабыми ссылками.

Сильная ссылка похожа на то, как ты держишься за шнурок с этим шариком. Пока вы держитесь за веревку, прикрепленную к воздушному шару, он не улетит.

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


68
+2 (если бы я только мог). Серьезно, действительно креативное объяснение!
Кон Антонакос

25
После полутора лет разработки iOS, я думаю, что сейчас я ясно понял, что strongи на weakсамом деле имею в виду.
Исуру

17
@ X.Li Сохраните цикл, как если бы у вас было 2 нити на баллоне, одна из которых принадлежит вам (поэтому вы владеете этим баллоном), а другая принадлежит баллону (так что этот баллон владеет вами). Поскольку у вас есть доступ только к вашей струне, как вы позволяете баллону уйти, если он не хочет уйти? Так что лучше владеть баллоном (сильным), в то время как баллон не владеет вами (слабым). Если вы хотите отпустить, просто перережьте строку :)
snakeninny

5
Прочитайте его профиль, он инструктор по iOS. Очень креативное объяснение !!
Снимаю шляпу

3
Я думаю, что атомную и неатомную можно описать как общественную туалетную комнату с несколькими дверями, с одним туалетом в центре. Когда кто-нибудь войдет в туалет через одну дверь, он может запереть все другие двери в туалете, если он не хочет испытывать неловкость. Ржунимагу. Спасибо за чтение этой бессмысленной аналогии.
Чен Ли Ён

24

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

слабый : назначит ему входящее значение, не сохраняя его.

Таким образом, основное отличие заключается в сохранении новой переменной. Обычно вы хотите сохранить его, но есть ситуации, когда вы не хотите его иметь, иначе вы получите цикл сохранения и не сможете освободить память объектов. Например. obj1 сохраняет obj2, а obj2 сохраняет obj1. Чтобы решить такую ​​ситуацию, вы используете слабые ссылки.


12

Дурацкий ответ: -

Я думаю, что объяснение дается в ответе выше, поэтому я просто скажу вам, где использовать STRONGи где использовать WEAK:

Использование Weak: - 1. Делегатов 2. Аутлетов 3. Подвидов 4. Органов управления и т. Д.

Использование Strong: - Остальное везде, что не входит в WEAK.


2
И что в нем содержится: P
Rajneesh071

3
WebView, MapView и т. д.
Шубхам Мишра

4
на самом деле большая часть подпредставления, которое мы перетаскиваем на раскадровку
шубхам мишра

8

сильные и слабые , эти ключевые слова вращаются вокруг владения объектами в Objective-C

Что такое владение объектом?

Переменные-указатели подразумевают владение объектами, на которые они указывают.

  • Когда у метода (или функции) есть локальная переменная, которая указывает на объект, говорят, что эта переменная владеет указанным объектом.
  • Когда у объекта есть переменная экземпляра, которая указывает на другой объект, говорят, что объект с указателем владеет указанным объектом.

Каждый раз, когда переменная указателя указывает на объект, этот объект имеет владельца и останется живым. Это известно как сильная ссылка.

Переменная может опционально не вступать во владение объектом, на который она указывает. Переменная, которая не становится владельцем объекта, называется слабой ссылкой.

Посмотрите подробное объяснение здесь Демистификация @property и атрибутов


6

Здесь Apple Documentation объяснила разницу между слабым и сильным свойством, используя различные примеры:

https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3

Здесь В этом блоге автор собрал все объекты недвижимости в одном месте. Это поможет сравнить характеристики свойств:

http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html


6

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

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


2

Чтобы понять сильные и слабые ссылки, рассмотрим пример ниже. Предположим, у нас есть метод с именем displayLocalVariable.

 -(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
  }

В приведенном выше методе область действия переменной myView ограничена методом displayLocalVariable, как только метод завершится, переменная myView, которая содержит объект UIView, будет освобождена из памяти.

Теперь, что если мы хотим сохранить переменную myView на протяжении всего жизненного цикла нашего контроллера представления. Для этого мы можем создать свойство с именем usernameView, которое будет иметь строгую ссылку на переменную myView (см. @property(nonatomic,strong) UIView* usernameView;И self.usernameView = myView;ниже в коде), как показано ниже:

@interface LoginViewController ()

@property(nonatomic,strong) UIView* usernameView;
@property(nonatomic,weak) UIView* dummyNameView;

- (void)displayLocalVariable;

@end

@implementation LoginViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

-(void)viewWillAppear:(BOOL)animated
{
     [self displayLocalVariable];
}

- (void)displayLocalVariable
{
   UIView* myView = [[UIView alloc] init];
   NSLog(@"myView tag is = %ld", myView.tag);
   self.usernameView = myView;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


@end

Теперь в приведенном выше коде вы можете видеть, что myView был назначен для self.usernameView, а self.usernameView имеет сильную ссылку (как мы объявили в интерфейсе с использованием @property) на myView. Следовательно, myView не будет освобожден из памяти до тех пор, пока self.usernameView не станет активным.

  • Слабая ссылка

Теперь рассмотрим назначение myName для dummyNameView, который является Слабой ссылкой, в self.dummyNameView = myView;отличие от Сильной ссылки Слабый будет удерживать myView только до тех пор, пока не будет Сильная ссылка на myView. Посмотрите код ниже, чтобы понять слабую ссылку,

-(void)displayLocalVariable
  {
     UIView* myView = [[UIView alloc] init];
     NSLog(@"myView tag is = %ld", myView.tag);
     self.dummyNameView = myView;
  }

В приведенном выше коде есть Слабая ссылка на myView (т. Е. Self.dummyNameView имеет Слабую ссылку на myView), но нет строгой ссылки на myView, поэтому self.dummyNameView не сможет содержать значение myView.

Теперь снова рассмотрим приведенный ниже код,

-(void)displayLocalVariable
      {
         UIView* myView = [[UIView alloc] init];
         NSLog(@"myView tag is = %ld", myView.tag);
         self.usernameView = myView;
         self.dummyNameView = myView;
      } 

В приведенном выше коде self.usernameView имеет ссылку Strong на myView, поэтому self.dummyNameView теперь будет иметь значение myView даже после завершения метода, поскольку myView имеет ссылку Strong, связанную с ним.

Теперь, когда мы делаем ссылку Strong на переменную, ее счетчик хранения увеличивается на единицу, и переменная не освобождается, пока ее счетчик не достигнет 0.

Надеюсь это поможет.


2019-07-25 12: 33: 15.479002 + 0530 StrongAndWeak [6329: 245483] Меня зовут = ABC 2019-07-25 12: 33: 15.479226 + 0530 StrongAndWeak [6329: 245483] Меня зовут для сильных = ABC 2019- 07-25 12: 33: 15.479418 + 0530 StrongAndWeak [6329: 245483] Меня зовут для слабого = ABC, в этом вы сказали, что у слабого свойства нет значения myname. Но я получаю значение myname как ABC для обеих ссылок .. ..?
Можете

@Raviteja_DevObal ARC не обещает сделать это немедленно (т. Е. Освободить строку @ "ABC"), но она обязательно получит освобождение позже ...
Махадев Мандале

@Raviteja_DevObal Как объяснить здесь строки являются плохим примером для этого. Я обновил свой ответ с помощью объекта UIView, надеюсь, это поможет.
Махадев Мандале

1

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

Неатомные : свойства такого типа используются в условиях, когда мы не хотим делить нашу точку или объект на разные одновременные потоки. Другими словами, Nonatomic instance заставляет наши свойства работать с одним потоком за раз. Надеюсь, это полезно для вас.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.