Operator Pengumpulan KVC pada nilai primitif

Bisakah operator koleksi digunakan pada nilai primitif?

Saya memiliki objek yang memiliki properti primitif duration.

@property (nonatomic) NSTimeInterval duration;

Saya memiliki NSArray objek tersebut dan saya ingin menggunakan operasi pengumpulan pada array untuk mendapatkan jumlah durasinya. Masalahnya adalah @"@sum.duration" malah mengharapkan NSNumber.

Apakah saya harus melakukan ini dengan cara lama, atau adakah cara untuk menggunakan primitif?


person RileyE    schedule 04.12.2013    source sumber


Jawaban (2)


Dari "Dukungan Skalar dan Struktur" dalam "Panduan Pemrograman Pengodean Nilai Kunci":

Pengkodean nilai kunci memberikan dukungan untuk nilai skalar dan struktur data dengan secara otomatis menggabungkan dan membuka nilai instans NSNumber dan NSValue.

So

NSNumber *sum = [array valueForKeyPath:@"@sum.duration"];

hanya berfungsi, meskipun duration adalah properti skalar. Contoh kecil mandiri:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject
@property(nonatomic, assign) NSTimeInterval duration;
@end

@implementation MyClass
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        MyClass *obj1 = [MyClass new];
        obj1.duration = 123.4;
        MyClass *obj2 = [MyClass new];
        obj2.duration = 456.7;
        NSArray *array = @[obj1, obj2];

        NSNumber *sum = [array valueForKeyPath:@"@sum.duration"];
        NSLog(@"sum = %@", sum);
    }
    return 0;
}

Keluaran: 580.1.

person Martin R    schedule 04.12.2013
comment
Menarik. Saya bertanya-tanya mengapa saya menerima kesalahan ini: Exception: [<__NSArrayM 0xe733040> valueForUndefinedKey:]: this class is not key value coding-compliant for the key sum.duration. - person RileyE; 04.12.2013
comment
@RileyE: Saya sudah mengujinya sebelum memposting jawabannya. Apakah Anda menulis @sum.duration atau sum.duration? - person Martin R; 04.12.2013
comment
@RileyE: Saya telah menambahkan contoh kerja pada jawaban saya. - person Martin R; 04.12.2013
comment
@RileyE, apakah Anda mencoba menggunakan valueForKey daripada valueForKeyPath:? - person Rob Napier; 04.12.2013
comment
@RobNapier Tangkapan bagus! Saya berangkat postingan ini karena alasan yang aneh, bukannya dokumentasi. - person RileyE; 04.12.2013
comment
Saya minta maaf atas ketidaknyamanan sebelumnya, Martin! Dan terima kasih! - person RileyE; 04.12.2013

Anda selalu dapat menambahkan properti lain:

@property (nonatomic) NSNumber *durationNumber;

dan mengimplementasikan pengambil dan penyetel:

- (NSNumber *)durationNumber {
    return [NSNumber numberWithDouble:self.duration];
}

- (void)setDurationNumber:(NSNumber *)durationNumber {
    self.duration = durationNumber.doubleValue;
}

Menerapkan penyetel dan pengambil akan menghambat sintesis otomatis ivar pendukung.

person godel9    schedule 04.12.2013
comment
Ya. Saya memikirkan hal itu, tetapi melakukannya dengan cara kuno tampaknya merupakan cara yang lebih optimal. Iterator loop for cepat yang berjalan satu kali dan tidak memerlukan alokasi NSNumber. Namun, terima kasih atas jawabannya! - person RileyE; 04.12.2013