完美KVO包括两个部分:正确添加观察者并正确删除观察者。
故事:
并非所有对象都具有相同的观察属性集。我有选择地添加关键路径观察器:
if(object.thumbnail_pic_url) [object addObserver:cell forKeyPath:@“thumbnail_picture”options:0 context:NULL];
可以删除对象。删除对象时,我必须删除观察者。数据库非常庞大和复杂,所以我绝对不想注册所有单元格来接收moc通知,如NSManagedObjectContextObjectsDidChangeNotification。但是如果必须的话,我可以接受在对象中添加一个单元格ivar,即使它再次成为好的Modle-View-Controller设计模式。
问题:在删除对象时,如何正确删除对象中所有已注册密钥路径的观察者(单元格)?
事实上,这是一个很大的问题,可以分为两个小问题:
如何确定要取消注册的关键路径?在删除对象后我无法查询其属性 - 这将导致无法填充的错误,因此我无法编写如下代码:
if(object.thumbnail_pic_url) [object removeObserver:cell forKeyPath:@“thumbnail_picture”];
我无法盲目地删除未注册的密钥路径的观察者 - 异常(无法删除密钥路径“thumbnail_picture”的观察者,因为它未被注册为观察者。)将被抛出。
答案 0 :(得分:3)
AN0,
有一个NSManagedObject方法只用于执行删除定时函数:-prepareForDeletion。
其文档声称:“您可以实现此方法以在删除对象之前执行所需的任何操作,例如在关系被拆除之前进行自定义传播,或使用键值观察重新配置对象。”
您还可以使用:-willTurnIntoFault和-didTurnIntoFault。但我认为使用-prepareForDeletion会更快乐。
安德鲁
P.S。此类方法记录在类引用中。我恭敬地建议您通过阅读文档来节省时间。
答案 1 :(得分:0)
在这里实现KVO的主要问题是你不知道对象什么时候被删除,至少不在NSManagedObject子类之外。你真正要做的是在NSManagedObject的子类上创建泛型委托并覆盖它的didChangeValueForKey:方法
// DataObservingManagedObject.h
#import <Foundation/Foundation.h>
#import <MMRecord/MMRecord.h>
@protocol DataObservingDelegate <NSObject>
-(void)valueChangedForKey:(NSString*)key andValue:(id)value;
@end
@interface DataObservingManagedObject : NSManagedObject
@property(nonatomic,weak)id<UserStatusDelegate> changeDelegate;
@end
//DateObservingManagedObject.m
#import "DateObservingManagedObject.h"
@implementation DateObservingManagedObject
@synthesize changeDelegate=_changeDelegate;
-(void)didChangeValueForKey:(NSString *)key{
[self.changeDelegate valueChangedForKey:key andValue:[self valueForKey:key]];
}
@end
答案 2 :(得分:0)
我认为错误在于步骤1。单元格应设计为显示不同的对象。单元格只是带有可显示任何内容的标签的视图。对表进行了优化,以将相同的单元格用于不同的数据对象。在您的VC中,创建一个configureCellWithEvent,configureCellWithVenue方法等,然后您可以使具有通用标识符的单元出队,并将其传递给这些方法。这样一来,您甚至根本不会出现何时添加移除观察者的问题,因为单元格不应该包含对象观察者。