إنشاء المنظمة من أجل القيم المحسوبة على أساس القيم المحسوبة

StackOverflow https://stackoverflow.com/questions/612474

سؤال

وهكذا لدي كائنين، فاتورة وInvoiceLineItem. InvoiceLineItem لديها خاصية تسمى cost وحيوي إنشاؤها استنادا على الخصائص الأخرى. للمساعدة في المنظمة من / الارتباطات يمكنني استخدام:

+ (NSSet *)keyPathsForValuesAffectingCost {
    return [NSSet setWithObjects:@"lineItemType", @"serviceCost", @"hourlyRate", @"timeInSeconds", @"productCost", @"quantityOfProduct", @"mileageCost", @"milesTraveled", nil];
}

وهذا يعمل كبيرة. عندما كنت تعديل خاصية مثل serivceCost التكلفة الرئيسية في جدول عرض التحديثات الجميلة.

في الكائن الفاتورة لدي NSMutableArray من InvoiceLineItems. فاتورة له خاصية مماثلة دعا totalCost. ويحسب من قبل بالتكرار على بنود وطالما لم يتم وضع علامة على بند كما حذف (الذي أقوم به لأسباب المزامنة) وتضيف ما يصل التكاليف ويخلق TOTALCOST.

والآن سؤالي / القضية. كيف أقوم بإعداد TOTALCOST الفاتورة بحيث أنه يعمل مع المنظمة من / الارتباطات عند واحد من تكاليف بند قد تغير؟

وحاولت إنشاء:

+ (NSSet *)keyPathsForValuesAffectingTotalCost {
    return [NSSet setWithObjects:@"lineItems.cost", nil];
}

ولكن لا يعمل. أنا في نهاية المطاف مع وجود خطأ في وحدة التحكم: [<NSCFArray 0x1499ff40> addObserver:forKeyPath:options:context:] is not supported. Key path: cost

هل كانت مفيدة؟

المحلول

لا أعتقد أن يتم دعم العلاقات لكثير لpropogation المنظمة من التلقائي. لا يقول صراحة الوثائق بطريقة أو أخرى، ولكن من ما أعرفه من المنظمة من عام، ومراقبة مفاتيح فرعية للكثير العلاقة تميل إلى أن تكون غير تافهة.

والطريقة أود أن هذا النهج سيكون لمراقبة يدويا الملكية cost كل كائن InvoiceLineItem، من خلال تنفيذ يمكنهم الدخول KVC لكثير للخاصية lineItems على الطبقة الفاتورة القيام مكالمة addObserver / removeObserver في إدراج / إزالة طرق على التوالي، ومن ثم تؤدي إلى تغيير totalCost يدويا باستخدام willChangeValueForKey: / didChangeValueForKey :. ذلك شيء من هذا القبيل (رمز رسمت تقريبا، التنازلات وغيرها):

- (void)insertObject:(InvoiceLineItem*)newItem inLineItemsAtIndex:(unsigned)index
{
    [newItem addObserver:newItem forKeyPath:@"cost" options:0 context:kLineItemContext];
    [lineItems insertObject:newItem atIndex:index];
}

- (void)removeObjectFromLineItemsAtIndex:(unsigned)index
{
    [[lineItems objectAtIndex:index] removeObserver:self forKeyPath:@"cost"];
    [lineItems removeObjectAtIndex:index];
}

- (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
{
    if (context == kLineItemContext)
    {
        [self willChangeValueForKey:@"totalCost"];
        [self didChangeValueForKey:@"totalCost"];
    }
}

نصائح أخرى

وكنت قد تحاول حل أقصر.

إضافة إلى ملف الرأس:

@property (retain, readonly) NSDecimalNumber *accountBalance;

إضافة إلى ملف تطبيق

- (NSDecimalNumber *)totalCost
{
    return [self valueForKeyPath:@"InvoiceLineItems.@sum.cost"];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top