Как связать редактируемый TextField со свойством только для чтения - PullRequest
3 голосов
/ 05 февраля 2010

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

Я пытаюсь привязать NSTextField к свойству NSString только для чтения в моем объекте данных. Мой объект данных похож на

...

@ свойство (только чтение) NSString * outCome;

- (Недействительными) otherMethodsAffectOutCome;

...

Я связал NSTextField со свойством result и в обработчике действий по умолчанию я назвал -otherMethodAffectOutCome, и я надеюсь, что / didChangeValueForKey запустит наблюдатель свойства outCome и вернет NSTextField.

Но это не работает, NSTextField будет аварийно завершать работу, потому что он пытается вернуть измененный текст с помощью метода setOutCome ... Я думаю, что мне нужно, чтобы NSTextField наблюдал за изменениями значения свойства, но не пытался вернуть значения при изменении текста Как мне это сделать?

Спасибо! -Jonny

Ответы [ 2 ]

1 голос
/ 30 июля 2012

Поскольку у вас уже есть собственный объект модели, есть два варианта лучше, чем переопределение -setValue:forUndefinedKey:.

  1. Просто измените свойство, чтобы оно не было readonly. Поскольку это объект Objective-C, он должен быть retain ed.

  2. Если вам нужно, чтобы свойство было выставлено как readonly для внешнего мира, вы можете вручную определить setOutCome: только в реализации; внешнему миру может показаться, что свойство доступно только для чтения, если только не придет какой-то мудрец и напрямую не вызовет -setOutCome:. Одной из таких мудрых идей является сама технология Cocoa Bindings.

    Это плохая идея, если вы не очень хорошо знаете, как должен работать установщик retain, и если вы очень осторожны с этим. Кроме того, вам придется преобразовать свойство в nonatomic - рекомендуемый параметр для iOS, но не для OS X.

  3. Наконец, - вот лучшее решение из этих трех , вариант метода 2. Помимо «категорий», классы также могут иметь «расширения». Проще говоря, вы должны думать о них как о не-настоящих категориях: дополнительные объявления методов, объявленные внутри вашего основного файла реализации (внутри файла .m) и реализованные внутри вашего основного файла реализации. Это используется для определения дополнительного частного интерфейса для вашего класса.

    В коде кажется, что это категория @interface, за исключением того, что круглые скобки пусты, без имени категории. Кроме того, это странная категория в том смысле, что она не соответствует @implementation.

    Чем это полезно для вас?

    Вы можете определить свойство в своем заголовке как (retain, readonly), но затем переопределить его как (retain) в расширении класса. @synthesize теперь будет создавать методы доступа как для получения, так и для установки.

Итак, давайте рассмотрим пример метода 3.

#import <Foundation.h>

@interface MyClass : NSObject
{
    id _myValue;
}
@property (retain, readonly) id myValue;
@end

//
#import "MyClass.h"

@interface MyClass ()
@property (retain) id myValue;
@end

@implementation MyClass
@synthesize myValue = _myValue;
@end

Теперь тот факт, что свойство фактически содержит установщик, является вашей деталью реализации, в то же время вы не написали свой собственный установщик. Возможно, это будет немного быстрее, чем если бы вы написали это самостоятельно, и вам не нужно было соблюдать осторожность в отношении порядка вызовов retain / release и операций присваивания.

0 голосов
/ 06 февраля 2010

Наконец, я нашел обходной путь, переопределив setValue: forUndefinedKey: метод в моем объекте данных. если имя ключа outCome, просто вернитесь без вызова super.

...