質問

私は、「マックOS Xのためのプログラミング」の「キー値コーディング」の章を通して働いています。私はスライダーやラベル、FIDOに結合し、両方の、int型とのインタフェースを構築しました。私は、スライダーを動かし、読み取り専用にFIDOのプロパティを設定した場合、まだそれが値です変更するラベルを引き起こします。私は、このためのエラーのいくつかの並べ替えを取得したいことを想定していました。プロパティが読み取り専用である場合には、どのように来るスライダーはまだプロパティに書き込むことができますか?私はそれが何のセッターが作成されていないだろう、とKVCは動作しないだろうと思いました。おかげます。

ここで私が使用しているコードです

#import <Cocoa/Cocoa.h>

@interface AppController : NSObject
{
    int fido;
}

@property (readonly, assign) int fido;

@end

#import "AppController.h"

@implementation AppController

@synthesize fido;

- (id)init
{
    [super init];
    [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
    NSNumber *n = [self valueForKey:@"fido"];
    NSLog(@"fido = %@", n);
    return self;
}
@end

altテキストhttp://idisk.me.com/nevan/Public /Pictures/Skitch/Window-20091001-174352.pngする

役に立ちましたか?

解決

AppController.hます:

@interface AppController : NSObject
{
        int fido;
}

@property (readonly, assign) int fido;
@end

輸入 "AppController.h"

@implementation AppController
@synthesize fido;
...
@end

この時点で、あなたはのAppControllerは-fidoメソッドを持っていることを宣言していると、あなたはその方法を合成しました。何-setFido:方法はありません。だから、以下の「仕事」を行い、なぜ?

- (id)init
{
        if (self=[super init]) {
            [self setValue:[NSNumber numberWithInt:5] forKey:@"fido"];
            NSNumber *n = [self valueForKey:@"fido"];
            NSLog(@"fido = %@", n);
        }
        return self;
}

(ところで:私は正しいパターンを実装するためにあなたの-initを固定)

KVCは値を設定または取得するには、のヒューリスティックを以下のため、

この作品。 -setValue:forKey:のための最初のルックスを-setFoo:するための呼び出し。見つからない場合は、そのインスタンス変数fooを探し、それを直接設定します。

あなたはfidoするインスタンス変数_fidoを変更した場合、セットが動作することに注意してください、それが合成されたメソッドを呼び出すようvalueForKeyは、私が64ビットによ以来、@synthesizeはfidoインスタンス変数を合成(0を返します。混乱、私は知っている。)。

あなたはbar、その後@synthesize foo=bar;を使用するようにIVARの名前を変更した場合、

、コードが実行時に失敗します。

あなたはわかります:

2009-10-01 08:59:58.081 dfkjdfkjfjkfd[24099:903] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<AppController 0x20000e700> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key fido.'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
(
    0   CoreFoundation                      0x00007fff85b055a4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x00007fff85c5a0f3 objc_exception_throw + 45
    2   CoreFoundation                      0x00007fff85b5caf9 -[NSException raise] + 9
    3   Foundation                          0x00007fff814e14f5 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 434
    4   dfkjdfkjfjkfd                       0x0000000100000d96 -[AppController init] + 130

他のヒント

読み取り専用プロパティを持つことは、コンパイラは、あなたがそのプロパティのsetter生成しないことを意味します。これは、KVO / KVCを経由して、それへの書き込みにはまだ法的です。

コンパイラディレクティブの@property@synthesizeは、問題の変数を取得および設定するメソッドを作成するには、単に速記の方法があります。

作成したsetterメソッドをsetFido:という名前で、getterメソッドは、単にfidoという名前が付けられます。

あなたが読み取り専用指定すると

、私は単純にsetterメソッドを作成しないようにコンパイラに指示することを信じているが、唯一のゲッター。これは、他の手段で変数を設定する方法で、バリアの任意の並べ替えを入れていません。

(私はすべてその権利を持っている願っています。幸運を!)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top