В чем разница между @property и геттерами/сеттерами для методов, которые выглядят как свойства?

Я понимаю ключевые различия/процесс. Свойство создает геттеры и сеттеры для переменной класса. Он также (теперь) синтезирует его с частной переменной с префиксом _.

Большой.

Теперь я хочу, чтобы некоторые методы действовали как свойство. Итак, у меня есть подкласс UIView, который имеет подпредставление UILabel.

Я хочу создать два метода - (NSString *)text и setText:(NSString *)text, чтобы установить и получить текст UILabel.

Очевидно, что это ДЕЙСТВУЕТ как свойство (вы можете сделать [myCustomElement text] и [myCustomElement setText:@"whatever"]), поэтому я чувствую, что должен определить свойство, но какая от этого польза, если она вообще есть?

Мои геттеры и сеттеры будут выглядеть так:

- (NSString *)text {
    return self.textLabel.text;
}

- (void)setText:(NSString *)text {
    self.textLabel.text = text;
}

person Thomas Clayson    schedule 05.02.2013    source источник
comment
Итак, каков ваш вопрос?   -  person Bhavin    schedule 05.02.2013
comment
Одно из отличий состоит в том, что свойства классов могут быть проанализированы ( class_copyPropertyList, class_getProperty, protocol_copyPropertyList, protocol_getProperty, property_getName, property_getAttributes) таким образом, который не может быть реализован вручную сеттерами и геттерами. Конечно, как установщики/геттеры свойств, так и реализованные вручную установщики/геттеры все еще могут быть проанализированы через class_copyMethodList.   -  person Nate Chandler    schedule 05.02.2013


Ответы (6)


Вы могли бы сделать это, но я бы отговаривал вас от этого. Наличие методов, которые выглядят как стандартные методы доступа (геттеры и сеттеры), но на самом деле обновляют элементы управления пользовательского интерфейса, в будущем станет источником путаницы. Это только подрывает удобочитаемость вашего кода, когда методы выполняют функции, которые не соответствуют общепринятым практикам. Кроме того, у вас уже есть недвижимость для вашего textLabel, так что эти методы мало что вам дадут.

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

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

person Rob    schedule 05.02.2013
comment
Хорошо, это имеет смысл. Я хотел сделать его максимально похожим на стандартный UILabel, поэтому setText и text были бы полезными функциями. Но я думаю, что по сути вы правы, я не должен пытаться сделать так, чтобы это выглядело как собственность, когда на самом деле это не так. :) - person Thomas Clayson; 05.02.2013

text уже является свойством (называемым text) свойства yourCustomElement textLabel (поэтому доступ к нему осуществляется с помощью записи через точку yourCustomElement.textLabel. текст)

в этом примере геттеры/сеттеры для свойства text должны/могут быть только внутри класса textLabel

Эти два метода являются просто удобными методами для установки/получения свойства свойства (хорошо, но они не являются геттерами/сеттерами и не должны их искать)

person blub    schedule 05.02.2013

Я думаю, что для вашего конкретного примера можно не определять свойство.

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

http://useyourloaf.com/blog/2011/02/08/understanding-your-objective-c-self.html

person Will Jenkins    schedule 05.02.2013

какая от этого польза, если есть?

Существует множество применений:

1) Вы можете использовать свойства для выполнения некоторых вычислений, обновления состояния объекта или чего-то вроде кэширования.

2) Слышали ли вы о Кодировании значений ключа (KVC) и Наблюдении за значением ключа (KVO) в Cocoa? Они зависят от свойств. Проверьте: Руководство по программированию KVC и Программирование KVO Руководство.

3) Используя свойства, вы можете поместить некоторый код управления памятью в методы доступа.

person Bhavin    schedule 05.02.2013
comment
Вы нашли вопрос тогда? хаха. Спасибо за это - исходя из вашего ответа и других, я не думаю, что правильно определять свойство для того, что я хочу делать. - person Thomas Clayson; 05.02.2013

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

Ex:

myCustomElement.text = @"whatever";
person Dan F    schedule 05.02.2013
comment
Вам не нужно объявлять свойство для использования записи через точку. myCustomElement.text = @"blah" вызовет -[CustomElement setText:], даже если свойство не объявлено. - person Nate Chandler; 06.02.2013

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

Однако ваш код не совпадает с @synthesis textLabel, потому что ваш код позволяет изменять только текст меток. @синтез позволит изменить все свойства.

Вот некоторая полезная информация о @синтезе/геттерах/сеттерах

http://useyourloaf.com/blog/2012/08/01/property-synchronous-with-xcode-4-dot-4.html

person Thorsten Niehues    schedule 05.02.2013
comment
Демоны ссылок не показывают, как создать геттер и сеттер с настраиваемым содержимым. - person AlexWien; 18.02.2013
comment
@AlexWien он уже знает, как делать геттеры / сеттеры (включены в вопрос), но эта ссылка описывает \@свойства и \@синтез, которые должны помочь ему решить, какой из них использовать - person Thorsten Niehues; 19.02.2013