문제

저는 "Mac OS X용 프로그래밍"의 "키 값 코딩" 장을 진행하고 있습니다.저는 슬라이더와 레이블이 있는 인터페이스를 구축했습니다. 둘 다 int인 fido에 바인딩되어 있습니다.fido의 속성을 읽기 전용으로 설정한 경우에도 슬라이더를 움직이면 레이블의 값이 변경됩니다.나는 이것에 대해 일종의 오류가 발생할 것이라고 가정했습니다.속성이 읽기 전용인 경우 슬라이더가 여전히 속성에 쓸 수 있는 이유는 무엇입니까?나는 Setter가 생성되지 않고 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

대체 텍스트 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;
}

(BTW : 올바른 패턴을 구현하기 위해 -INIT를 수정했습니다)

이것은 KVC가 a를 따르기 때문에 작동합니다 휴리스틱 값을 설정하거나 얻습니다. 전화 -setValue:forKey: 먼저 찾습니다 -setFoo:. 찾을 수없는 경우 인스턴스 변수를 찾습니다. foo 직접 설정합니다.

인스턴스 변수를 변경하면 참고하십시오 fido 에게 _fido, 세트는 작동하지만 valueForKey 합성 된 방법을 호출 할 때 0을 반환합니다 (64 비트이기 때문에 @Synthesize는 합성 fido 인스턴스 변수. 혼란 스럽습니다.

Ivar의 이름을 변경한다면 bar 그리고 사용하십시오 @synthesize foo=bar;, 런타임에 코드가 실패합니다.

당신은 볼 수:

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

다른 팁

읽기 전용 속성이 있다는 것은 컴파일러가 해당 속성에 대한 설정자를 생성하지 않는다는 것을 의미합니다.KVO/KVC를 통해 쓰는 것은 여전히 ​​합법적입니다.

컴파일러 지침 @property 그리고 @synthesize 문제의 변수를 얻고 설정하는 메소드를 작성하는 속기 방법입니다.

생성 된 세터 메소드의 이름이 지정되었습니다 setFido:, 그리고 getter 방법의 이름이 지정되었습니다 fido.

Readonly를 지정하면 컴파일러가 세터 메소드를 만들지 말고 getter 만 말하면 간단하게 알려줍니다. 변수를 다른 방법으로 설정하는 방식에 어떤 종류의 장벽도 두지 않습니다.

(내가 그 모든 것을 얻었 으면 좋겠어. 행운을 빌어 요!)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top