إنشاء المنظمة من أجل القيم المحسوبة على أساس القيم المحسوبة
-
03-07-2019 - |
سؤال
وهكذا لدي كائنين، فاتورة و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"];
}