首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >核心数据-监视更改并注册本地通知

核心数据-监视更改并注册本地通知
EN

Stack Overflow用户
提问于 2011-01-29 06:26:13
回答 2查看 7.5K关注 0票数 5

我对核心数据和KVC比较陌生,但我想要一些关于注册核心数据对象中的更改的侦听器的指针。情况是这样的:

我有一个名为PatientNSManagedObject和另一个名为Medication的and。一个Patient可能有多个Medications,一个Medication有一个startOnendOn日期。

我想以某种方式侦听所有Medication对象的endOn属性的更改。当发生更改时,我希望在iOS设备上安排一个本地通知。我以前使用过本地通知,但不知道在这个上下文中应该把它的代码放在哪里。

我是否要在App Delegate中创建调度代码,并以某种方式注册App Delegate以侦听Medication对象中的更改?是否需要将其连接到NSManagedObjectContext

这是怎么做的?指针将非常受欢迎!

谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-29 08:56:27

对于键值观察,您需要一些实例来进行观察。有时,它可以是调用-setEndOn: on药物的同一对象;有时,它可能必须是其他对象。让我们假设您的应用程序有一个MedicationManager类-其中创建了一个实例。并且,进一步假设MedicationManager有一个实例方法-createMedicationWithName:startOn:endOn:如下所示:

代码语言:javascript
复制
- (Medication*) createMedicationWithName:(NSString*)medName startOn:(NSDate*)startDate endOn:(NSDate*)endDate
    {
    //  Create and configure a new instance of the Compound entity 
    Medication *newMedication = (Medication *)[NSEntityDescription insertNewObjectForEntityForName:@"Medication"
                                                inManagedObjectContext:[self managedObjectContext]];
    [newMedication setName:medName];
    [newMedication setStartOn:startDate];
    [newMedication setEndOn:endDate];

    //  Set up KVO
    [newMedication addObserver:self
                    forKeyPath:@"endOn"
                    options:NSKeyValueObservingOptionNew
                    context:nil];

    return newCompound;
    }


- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
                                                    change:(NSDictionary *)change 
                                                    context:(void *)context
    {
    if ([keyPath isEqualToString:@"endOn"])
        {
        //  ... schedule local notification on the iOS device for (Medication*)object.
        return;
        }
    }

或者类似的东西。

注意,当你删除一种药物时,你会想要removeObserver...此外,当启动你的应用程序时,你需要建立MedicationManager作为现有药物的观察者。我认为这可以像迭代所有药物并为每个药物调用addObserver一样简单。如果你有很多药物,那么你可能想要以一种更“懒惰”的方式来做这件事(例如,在-awakeFromFetch中)。

票数 7
EN

Stack Overflow用户

发布于 2011-01-29 11:12:30

在第一次从存储中获取对象以及创建对象时,您都必须注册观察者。不必在第一次获取时遍历所有条目(这很容易出错,特别是在iPhone上,因为未修改的获取的对象在未保留时可能会出错),只需使用awakeFromFetch和awakeFromInsert消息。

此外,在下面的示例代码中,您还可以通过对存储此信息的患者创建瞬态属性来跟踪患者的聚合信息,如最快的startOn和最快的endOn。下面的代码观察药物中endOn的变化,并使您能够更新前面提到的患者的瞬时“最快endOn”或“最快startOn”。

代码语言:javascript
复制
- (void)addMyObservers
{
    registeredObservers_ = YES;
    [self addObserver:self forKeyPath:@"endOn" options:NSKeyValueObservingOptionNew context:nil]; 
}

- (void)awakeFromInsert 
{
    // called when you create this object
    [super awakeFromInsert];
    [self addMyObservers];
}

- (void)awakeFromFetch
{
    // called when you fetch this old object from the store
    [super awakeFromFetch];
    [self addMyObservers];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualToString:@"endOn"]) 
    {
        id newValue = [change objectForKey:NSKeyValueChangeNewKey];
        // someone changed endOn so do something with this "newValue"
        // check to see if the Patient needs the transient property for the soonest medication updated
        // update any local notification schedule 
    }
}

// this is only required if you want to update the Patient's transient property for the soonest endOn or 
- (void)setPatient:(Patient *)patient
{
    [self willChangeValueForKey:@"patient"];
    [self setPrimitivePatient:patient];
    [self didChangeValueForKey:@"patient"];

    // check to see if the Patient needs the transient property for the soonest medication updated
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4833655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档