ตัวดำเนินการรวบรวม KVC ในค่าดั้งเดิม

ตัวดำเนินการรวบรวมสามารถใช้กับค่าดั้งเดิมได้หรือไม่?

ฉันมีวัตถุที่มีคุณสมบัติดั้งเดิม duration

@property (nonatomic) NSTimeInterval duration;

ฉันมี NSArray ของอ็อบเจ็กต์ดังกล่าว และฉันต้องการใช้การดำเนินการรวบรวมบนอาร์เรย์เพื่อรับ ผลรวม ของระยะเวลา ปัญหาคือ @"@sum.duration" คาดหวัง NSNumber แทน

ฉันจะต้องทำแบบนี้แบบเดิมๆ หรือมีวิธีใช้แบบพื้นฐานหรือไม่?


person RileyE    schedule 04.12.2013    source แหล่งที่มา


คำตอบ (2)


จาก "การสนับสนุนสเกลาร์และโครงสร้าง" ใน "คู่มือการเขียนโปรแกรมการเข้ารหัสคีย์-ค่า":

การเข้ารหัสคีย์-ค่าให้การสนับสนุนค่าสเกลาร์และโครงสร้างข้อมูลโดยการห่อและแกะค่าอินสแตนซ์ NSNumber และ NSValue โดยอัตโนมัติ

So

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

ใช้งานได้แม้ว่า duration จะเป็นคุณสมบัติสเกลาร์ก็ตาม ตัวอย่างเล็กๆ น้อยๆ ที่มีอยู่ในตัวเอง:

#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;
}

เอาท์พุต: 580.1

person Martin R    schedule 04.12.2013
comment
น่าสนใจ. ฉันสงสัยว่าเหตุใดฉันจึงได้รับข้อผิดพลาดนี้: Exception: [<__NSArrayM 0xe733040> valueForUndefinedKey:]: this class is not key value coding-compliant for the key sum.duration. - person RileyE; 04.12.2013
comment
@RileyE: ฉันได้ทดสอบก่อนที่จะโพสต์คำตอบ คุณเขียน @sum.duration หรือ sum.duration? - person Martin R; 04.12.2013
comment
@RileyE: ฉันได้เพิ่มตัวอย่างการทำงานให้กับคำตอบของฉัน - person Martin R; 04.12.2013
comment
@RileyE คุณพยายามใช้ valueForKey มากกว่า valueForKeyPath: หรือไม่? - person Rob Napier; 04.12.2013
comment
@RobNapier จับได้ดี! ฉันกำลังจะปิด โพสต์นี้ด้วยเหตุผลแปลก ๆ แทนที่จะเป็น เอกสารประกอบ - person RileyE; 04.12.2013
comment
ฉันขอโทษสำหรับความไม่สะดวกที่เกิดขึ้นก่อนหน้านี้ มาร์ติน! และขอบคุณ! - person RileyE; 04.12.2013

คุณสามารถเพิ่มคุณสมบัติอื่นได้ตลอดเวลา:

@property (nonatomic) NSNumber *durationNumber;

และใช้ทั้ง getter และ setter:

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

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

การใช้ทั้งตัวเซ็ตและตัวทะเยอทะยานจะยับยั้งการสังเคราะห์ ivar สำรองโดยอัตโนมัติ

person godel9    schedule 04.12.2013
comment
ใช่. ฉันคิดอย่างนั้น แต่การทำแบบเก่าดูเหมือนจะเป็นวิธีที่ดีที่สุดในการทำแบบนั้น Quick for loop iterator ที่ทำงานเพียงครั้งเดียวและไม่จำเป็นต้องมีการจัดสรร NSNumber อย่างไรก็ตาม ขอบคุณสำหรับคำตอบ! - person RileyE; 04.12.2013