@property сохранить, назначить, скопировать, неатомный в Objective-C - PullRequest
205 голосов
/ 13 февраля 2010

Как кто-то, кто является новичком в Objective-C, кто-то может дать мне обзор сохранения, назначения, копирования и любых других, которые мне не хватает, которые следуют директиве @property? Что они делают и почему я хочу использовать один поверх другого?

Ответы [ 4 ]

286 голосов
/ 10 апреля 2013

Прежде чем вы узнаете об атрибутах @property, вы должны знать, для чего используется @ property.

  • @ property предлагает способ определения информации, которую класс должен инкапсулировать. Если вы объявите объект / переменную, используя @ property , тогда этот объект / переменная будет доступен для других классов, импортирующих его класс.

  • Если вы объявляете объект, используя @ property в заголовочном файле, то вы должны синтезировать его, используя @ synthesize в файле реализации. Это делает объект KVC-совместимым . По умолчанию компилятор синтезирует методы доступа для этого объекта.

  • Методы доступа: сеттер и геттер.

* * Пример тысяча двадцать восемь: .h
@interface XYZClass : NSObject
@property (nonatomic, retain) NSString *name;
@end

.m

@implementation XYZClass
@synthesize name;
@end

Теперь компилятор будет синтезировать методы доступа для name .

XYZClass *obj=[[XYZClass alloc]init];
NSString *name1=[obj name]; // get 'name'
[obj setName:@"liza"]; // first letter of 'name' becomes capital in setter method
  • Список атрибутов @ property

    атомарный, неатомный, сохранить, скопировать, только для чтения, перезаписать, назначить, сильный, метод получения = метод, метод установки = метод, unsafe_unretained

  • atomic - поведение по умолчанию. Если объект объявлен как атомарный, он становится потокобезопасным. Потокобезопасный означает, что одновременно только один поток определенного экземпляра этого класса может иметь контроль над этим объектом.

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

@property NSString *name; //by default atomic`
@property (atomic)NSString *name; // explicitly declared atomic`
  • неатомный не является потокобезопасным. Вы можете использовать атрибут неатомного свойства, чтобы указать, что синтезированные средства доступа просто устанавливают или возвращают значение напрямую, без каких-либо гарантий того, что произойдет, если к одному и тому же значению одновременно обращаются из разных потоков.

По этой причине доступ к неатомарному свойству быстрее, чем к атомарному.

@property (nonatomic)NSString *name;   
  • сохранить требуется, когда атрибут является указателем на объект.

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

@property (retain)NSString *name;
  • copy Если вы используете copy, вы не можете использовать retain. Использование экземпляра экземпляра класса будет содержать собственную копию.

Даже если изменяемая строка установлена ​​и впоследствии изменена, экземпляр захватывает любое значение, которое он имеет во время установки. Методы получения и получения не будут синтезированы.

@property (copy) NSString *name;

сейчас

NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];    
xyzObj.name = nameString;    
[nameString appendString:@"Pizza"]; 

имя останется неизменным.

  • readonly Если вы не хотите разрешать изменение свойства с помощью метода setter, вы можете объявить свойство только для чтения.

Компилятор будет генерировать геттер, но не сеттер.

@property (readonly) NSString *name;
  • readwrite - это поведение по умолчанию. Вам не нужно явно указывать атрибут readwrite.

Это противоположно readonly.

@property (readwrite) NSString *name;
  • assign создаст установщик, который присваивает значение переменной экземпляра напрямую, а не копирует или сохраняет его. Это лучше всего подходит для примитивных типов, таких как NSInteger и CGFloat, или для объектов, которыми вы не владеете напрямую, таких как делегаты.

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

@property (assign) NSInteger year;
  • Сильный является заменой для удержания.

Поставляется с ARC.

@property (nonatomic, strong) AVPlayer *player; 
  • getter = method Если вы хотите использовать другое имя для метода getter, можно указать пользовательское имя, добавив атрибуты в свойство.

В случае логических свойств (свойств, имеющих значение YES или NO), обычно метод getter начинается со слова «is»

@property (getter=isFinished) BOOL finished;
  • setter = method Если вы хотите использовать другое имя для метода setter, можно указать пользовательское имя, добавив атрибуты в свойство.

Метод должен заканчиваться двоеточием.

@property(setter = boolBool:) BOOL finished;
  • unsafe_unretained Есть несколько классов в Cocoa и Cocoa Touch, которые еще не поддерживают слабые ссылки, что означает, что вы не можете объявить слабое свойство или слабую локальную переменную, чтобы отслеживать их. Эти классы включают NSTextView, NSFont и NSColorSpace и т. Д. Если вам нужно использовать слабую ссылку на один из этих классов, вы должны использовать небезопасную ссылку.

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

@property (unsafe_unretained) NSObject *unsafeProperty;

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

@property (readonly, getter=isFinished) BOOL finished;
266 голосов
/ 22 октября 2011

Статья, на которую ссылается MrMage, больше не работает. Итак, вот что я выучил в своем (очень) кратковременном кодировании в Objective-C:

неатомные и атомные - «Атомный» по умолчанию. Всегда используйте «неатомный». Я не знаю почему, но в книге, которую я прочитал, говорится, что есть «редко причина» для использования «атомной». (Кстати: книга, которую я прочитал, является книгой BNR "Программирование на iOS".)

readwrite против readonly - «readwrite» является значением по умолчанию. Когда вы @synthesize, для вас будут созданы как геттер, так и сеттер. Если вы используете «только чтение», сеттер не будет создан. Используйте его для значения, которое вы не хотите изменять после создания объекта.

сохранить против копирования против присвоить

  • «Назначить» является значением по умолчанию. В установщике, созданном @synthesize, значение будет просто присвоено атрибуту. Насколько я понимаю, «назначить» следует использовать для не указателей атрибутов.
  • "retain" необходим, когда атрибут является указателем на объект. Сеттер, сгенерированный @synthesize, сохранит (или добавит счетчик сохранения) объект. Вам нужно будет отпустить объект, когда вы закончите с ним.
  • «копия» необходима, когда объект изменчив. Используйте это, если вам нужно, чтобы значение объекта было таким, как оно есть в данный момент, и вы не хотите, чтобы это значение отражало какие-либо изменения, сделанные другими владельцами объекта. Вам нужно будет освободить объект, когда вы закончите с ним, потому что вы сохраняете копию.
146 голосов
/ 21 марта 2013

Прочитав много статей, я решил собрать всю информацию об атрибутах:

  1. атомарный // по умолчанию
  2. неатомической
  3. strong = сохранить // по умолчанию
  4. Слабый = unsafe_unretained
  5. сохранить
  6. назначить // по умолчанию
  7. unsafe_unretained
  8. копия
  9. * только для чтения * 1023
  10. readwrite // по умолчанию

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

Большое спасибо всем людям, которые дают лучшие ответы здесь !!

Атрибуты переменных свойств или модификаторы в iOS

Вот пример описания из статьи

  1. атомное -Атомный означает, что только один поток имеет доступ к переменной (статический тип). -Атомный потокобезопасный. - но это медленно в производительности -атомное поведение по умолчанию -Атомные средства доступа в среде без сбора мусора (т.е. при использовании retain / release / autorelease) будут использовать блокировку для убедитесь, что другой поток не мешает правильной установке / получению значения. Это на самом деле не ключевое слово.

Пример:

@property (retain) NSString *name;

@synthesize name;
  1. неатомический -Nonatomic означает многопоточный доступ к переменной (динамический тип). -Nonatomic это поток небезопасно. - но это быстро в производительности -Nonatomic НЕ является поведением по умолчанию, нам нужно добавить ключевое слово nonatomic в атрибуте свойства. -это может привести к неожиданному поведению, когда два разных процесса (потока) одновременно обращаются к одной и той же переменной.

Пример: * * тысяча пятьдесят-семь

@property (nonatomic, retain) NSString *name;

@synthesize name;

Объясните:

Предположим, что есть атомарное строковое свойство с именем "name", и если вы вызываете [self setName: @ "A"] из потока A, вызовите [self setName: @ "B"] из потока B и вызовите [self name] из потока C, тогда все операции в другом потоке будут выполняться последовательно, что означает, что если один поток выполняет установщик или получатель, тогда другие потоки будут ждать , Это делает свойство "name" доступным для чтения / записи, но если другой поток D одновременно вызывает [name release], то эта операция может привести к сбою, так как здесь нет никакого вызова setter / getter. Это означает, что объект является безопасным для чтения / записи (ATOMIC), но не потокобезопасным, поскольку другие потоки могут одновременно отправлять объекту сообщения любого типа. Разработчик должен обеспечить безопасность потоков для таких объектов.

Если свойство "name" было неатомичным, то все потоки в приведенном выше примере - A, B, C и D будут выполняться одновременно, что приведет к непредсказуемому результату. В случае атомарного, любой из A, B или C будет выполняться первым, но D все еще может выполняться параллельно.

  1. Сильный (iOS4 = сохранить) -это говорит "держи это в куче, пока я не укажу на это больше" Другими словами: «Я владелец, вы не можете иметь дело с этим до того, как прицельтесь на то же самое, что и удержите» -Вы используете сильные, только если вам нужно сохранить объект. -По умолчанию все переменные экземпляра и локальные переменные являются сильными указателями. -Мы обычно используем strong для UIViewControllers (родителей элемента пользовательского интерфейса) -strong используется с ARC, и он в основном помогает вам, не беспокоясь о сохранении счета объекта. ARC автоматически выпускает его для вас, когда вы закончите. Использование ключевого слова strong означает, что вы владеете объектом.

Пример:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;
  1. слабый (iOS4 = unsafe_unretained) -это говорит: «Держите это, пока кто-то еще сильно на это указывает» - то же самое, что присваивать, не сохранять или освобождать -Слабая ссылка - это ссылка, которую вы не сохраняете. -Мы обычно используем слабый для IBOutlets (потомков UIViewController). Это работает, потому что только дочерний объект должен существовать до тех пор, пока существует родительский объект. -слабая ссылка - это ссылка, которая не защищает указанный объект от сбора сборщиком мусора.-Слабость, по сути, присваивать, оставшееся свойство. За исключением случаев, когда объект освобожден, для слабого указателя автоматически устанавливается ноль

Пример:

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

Сильное и слабое объяснение, Благодаря Би Джей Гомеру :

Представьте, что наш объект - собака, и что собака хочет убежать (быть освобожденной). Сильные указатели похожи на поводок на собаку. Пока у вас есть поводок, привязанный к собаке, собака не убежит. Если пять человек прикрепят поводок к одной собаке (пять сильных указателей на один объект), то собака не убежит, пока все пять поводков не отсоединятся. Слабые указатели, с другой стороны, похожи на маленьких детей, указывающих на собаку и говорящих "Смотри! Собака!" Пока собака все еще на поводке, маленькие дети все еще могут видеть собаку, и они все еще будут указывать на нее. Однако, как только поводки отстегнуты, собака убегает независимо от того, сколько на нее указывают маленькие дети. Как только последний сильный указатель (поводок) больше не указывает на объект, объект будет освобожден, а все слабые указатели будут обнулены. Когда мы используем слабые? Единственный раз, когда вы хотите использовать слабый, это если вы хотите избежать сохранения циклов (например, родитель сохраняет ребенка, а ребенок сохраняет родителя, поэтому ни один из них не освобождается).

  1. сохранить = сильный - сохраняется, старое значение освобождается и ему присваивается -retain указывает, что новое значение должно быть отправлено -retain при присвоении, а старое значение отправлено -release -сдержать так же, как сильный. -apple говорит, что если вы напишите сохранить, он будет автоматически преобразован / работать только как сильный. -методы типа «alloc» включают в себя неявное «retain»

Пример:

@property (nonatomic, retain) NSString *name;

@synthesize name;
  1. присвоить -assign является значением по умолчанию и просто выполняет присвоение переменной -assign - это атрибут свойства, который сообщает компилятору, как синтезировать реализацию метода установки свойства -Я бы использовал для примитивных свойств C назначение и для слабых ссылок на объекты Objective-C слабые.

Пример:

@property (nonatomic, assign) NSString *address;

@synthesize address;
  1. unsafe_unretained

    -unsafe_unretained - квалификатор владения, который сообщает ARC, как вставлять вызовы удержания / освобождения -unsafe_unretained - это версия ARC для присвоения.

Пример:

@property (nonatomic, unsafe_unretained) NSString *nickName;

@synthesize nickName;
  1. копия -копия требуется, когда объект изменчив. -copy указывает, что новое значение должно быть отправлено -copy при назначении, а старое значение отправлено -release. -copy похоже на то, что retain возвращает объект, который вы должны явно освободить (например, в dealloc) в средах без сбора мусора. -Если вы используете копию, то вам все еще нужно выпустить ее в dealloc. -Используйте это, если вам нужно, чтобы значение объекта было таким, как оно есть в данный момент, и вы не хотите, чтобы это значение отражало какие-либо изменения, сделанные другими владельцы объекта. Вам нужно будет освободить объект, когда вы закончите с ним, потому что вы сохраняете копию.

Пример: * * тысяча сто двадцать три

@property (nonatomic, copy) NSArray *myArray;

@synthesize myArray;
8 голосов
/ 29 января 2013

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

отсутствует.

Неатомный означает, что к элементу может обращаться несколько потоков. Это поток небезопасный

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...