سؤال

أنا أعمل من خلال الفصل "ترميز القيمة الرئيسية" في "البرمجة لنظام التشغيل Mac OS X". لقد قمت ببناء واجهة مع شريط تمرير وتسمية، كلاهما ملزم بدفو، وهو كثف. إذا قمت بتعيين الخاصية ل FIDO إلى Readonly، فلن يؤدي تحريك شريط التمرير إلى تغيير الملصق لتغييره. لقد افترضت أن أحصل على نوع من الخطأ لهذا. إذا كان الخاصية Readonly، فماذا لا يزال بإمكان المنزلق الكتابة إلى العقار؟ اعتقدت أنه لن يكون لديه أي خلق من المؤشرين، ولم تعمل 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;
}

(راجع للشغل: لقد قمت بإصلاحك لتطبيق النمط الصحيح)

هذا يعمل لأن KVC يتبع ارشادي لتعيين أو الحصول على القيمة. دعوة إلى -setValue:forKey: يبحث أولا عن -setFoo:. وبعد إذا لم يتم العثور عليها، فهذا يبحث عن متغير المثيل foo ويضعها مباشرة.

لاحظ أنه إذا قمت بتغيير متغير المثيل fido ل _fido, ، سوف تعمل المجموعة، ولكن valueForKey سيعود 0 لأنه يستدعي الطريقة المركبة (لأنني في 64 بت، يتنقل snythesize 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

نصائح أخرى

وجود خاصية Readonly تعني أن برنامج التحويل البرمجي لن يولد لك Sentter لهذا الممتلكات. لا يزال من القانوني أن يكتب إليها عبر KVO / KVC.

توجيهات المحول البرمجي @property و @synthesize هي مجرد طرق تخثر لإنشاء طرق للحصول على المتغير وتعيينها في السؤال.

يتم تسمية طريقة STERTER التي تم إنشاؤها setFido:, ، وطريقة getter اسمه فقط fido.

عندما تحدد Readonly، أعتقد أن التحويل البرمجي ببساطة عدم إنشاء طريقة SETERT، ولكن فقط Getter. لا يضع أي نوع من الحاجز في طريقة تحديد المتغير بوسائل أخرى.

(آمل أن يكون لدي كل هذا صحيح. حظا سعيدا!)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top