self.variable и переменная разница
В чем разница между self.myVariable = obj;
а также myVariable = obj;
когда я использую @propery
/@synthesize
создать `myVariable?
6 ответов
Важно отметить, что точечный синтаксис преобразуется компилятором в простой вызов objc_msgSend: то есть, под ним он действует точно так же, как сообщение, отправляемое аксессору для этой переменной. Таким образом, все три из следующего эквивалентны:
self.myVariable = obj;
[self setMyVariable:obj];
objc_msgSend(self, @selector(setMyVariable:), obj);
Конечно, это означает, что использование точечного синтаксиса фактически приводит к полной отправке сообщения, то есть к вызову новой функции и всех накладных расходов, связанных с ней. Напротив, использование простого присваивания (myVariable = obj;) не влечет за собой никаких накладных расходов, но, конечно, оно может использоваться только внутри методов экземпляра рассматриваемого класса.
Директива @synthesize указывает компилятору генерировать методы доступа для ваших переменных-членов в соответствии со спецификациями, указанными в директиве @property в вашем файле.h. (То есть, если вы укажете retain, установщик сохранит переменную, а если вы укажете copy, он скопирует ее.)
Средства доступа будут (если вы не укажете иначе) с именами propertyName и setPropertyName.
С использованием. нотация (примечание, а не синтаксис self, как указано выше) говорит о том, что вы хотите использовать средства доступа (хорошо, если вы устанавливаете строки и хотите убедиться, например, в том, что счет сохранения верен).
Итак, в вашей реализации класса:
- self.bill = fred вызовет метод доступа setBill.
- bill = fred установит счет на fred напрямую, без прохождения через аксессор.
Одно из различий, которые я обнаружил при запуске разработки Какао, заключается в том, что я установил переменную для использования синтаксиса @Property/@Synthesize, и я не использовал self.myVariable = obj или [self setMyVariable: obj], а вместо этого myVariable = obj, объект не сохраняется, если объект освобождается позже. (Предполагая, что @Property был настроен на использование retain.)
Причина в том, что счет сохранения не устанавливается при использовании myVariable = obj, и когда объект освобожден, счет теперь равен нулю. (Если только вы не сохраните его сами) Но с помощью средства доступа он запишется за вас. (Опять же, при условии, что вы настроили его, чтобы использовать retain, когда он был объявлен).
Shyne
Если я могу добавить одну важную заметку к этому. Ответ выше, все классные, поэтому я не буду добавлять техническую сторону. Но только это:
Если вы создаете синтезированное свойство
@synthesize myProp;
Всегда используйте шаблон self.myProp, чтобы установить его.
self.myProp = newVal;
Это кажется действительно очевидным, но это важно. Это правда, что просто нет причин делать это, но пока вы действительно не поймете, как создаются синтезированные сеттеры, вы просто хотите предположить, что вы ДОЛЖНЫ использовать самость. шаблон для установки значения.
Честно говоря: это избавит вас от множества ночных сессий отладки. Неполноценные нарушения доступа к памяти являются просто худшими для отладки.
self
синтаксис использует метод доступа, другой синтаксис - нет. Это может иметь большое значение, если средство доступа делает что-то большее, чем просто назначает новое значение. См. Раздел " Объявленные свойства" в учебнике Objective-C.
Другие ответы верны, разница в том, что точечная нотация вызывает изменение ивара через аксессуар, а не напрямую.
Пока вы не знаете, что делаете, я рекомендую использовать точечную запись (т.е. self.propertyName = ...
). Cocoa / Obj-C делает многое с кодированием значения ключа, и, хотя SDK для телефона не использует его в полной мере (с такими вещами, как привязки), в конце концов, это произойдет. Привыкание к использованию аксессоров сейчас избавит вас от многих головных болей в будущем.
Использование методов доступа также дает вам возможность переопределить их и предоставить больше функциональных возможностей, если вам это нужно. Просто изменяя значение ивара, вы лишаете себя этой возможности.