标签: nsmanagedobject

检测对NSManagedObject的特定属性的更改

如何检测对特定属性的更改NSManagedObject?在我的核心数据数据模型中,我有一个Product代表待售产品的实体.该Product实体有几个属性:price,sku,weight,numberInStock,等每当price一个属性Product的变化,我需要执行冗长的计算.因此,我想知道任何更改的price属性,[编辑]即使该更改来自合并另一个线程上保存的上下文.这样做的好方法是什么?我的商店里有成千上万的物品; 显然,向每个人发送一条消息是不可行的. ProductProductaddObserver

我一直用NSManagedObjectContextObjectsDidChangeNotification检测的变化,但它只是通知我一个管理对象发生了变化,而不是该对象的属性发生变化.每当a发生任何变化时,我都可以重做计算Product,但只要不相关的属性发生变化,就会导致无用的重新计算.我正在考虑创建一个Price实体(只包含一个price属性)并使用Product和之间的一对一关系Price.这样,我可以检测到Price对象的更改,以便开始计算.这对我来说似乎过于愚蠢.有没有更好的办法?

更新:

@railwayparade指出我可以使用该changedValues方法NSManagedObject确定每个更新对象的哪些属性已更改.我完全错过了这个方法,如果没有在后台线程上进行更改并将其合并到主线程的上下文中,它将完全解决我的问题.(见下一段.)

我完全错过了关于NSManagedObjectContextObjectsDidChangeNotification工作方式的微妙之处.据我所知,当另一个线程上保存的托管对象上下文合并到主线程上的上下文(使用a mergeChangesFromContextDidSaveNotification:)时,结果NSManagedObjectContextObjectsDidChangeNotification 包含有关当前位于主线程的托管对象上下文中的对象的更改信息.如果更改的对象不在主线程的上下文中,则它不会成为通知的一部分.这很有道理,但不是我所期待的.因此,为了获得更详细的更改信息,我想使用一对一关系而不是属性实际上需要检查后台线程NSManagedObjectContextDidSaveNotification,而不是主线程NSManagedObjectContextObjectsDidChangeNotification.当然,简单地使用changedValues方法会更聪明NSManagedObject正如@railwayparade帮助指出的那样.但是,我仍然存在这样的问题:主线程上合并的更改通知不一定包含后台线程上所做的所有更改.

iphone notifications core-data nsmanagedobject

21
推荐指数
2
解决办法
2万
查看次数

比较两个NSManagedObjects

我有一些代码循环遍历NSManagedObjects数组,并在找到存储在实例变量中的某条记录时停止.我能够设法查看它们是否是同一记录(不是等效记录,特定记录)的唯一方法是比较objectID的URIRepresentations.这肯定不是最好的方法.我正在做:

if ([[[obj1 objectID] URIRepresentation] isEqualTo: [[_obj2 objectID] URIRepresentation]]) {
  NSLog(@"Match");
}
Run Code Online (Sandbox Code Playgroud)

以下代码永远不会匹配,即使我NSLog的objectIDs,并看到它们实际上是完全相同的.

if ([[obj1 objectID] isEqualTo: [_obj2 objectID]]) {
  NSLog(@"Match");
}
Run Code Online (Sandbox Code Playgroud)

core-data objective-c nsmanagedobject

21
推荐指数
3
解决办法
9388
查看次数

哪些Swift类型可以在Objective-C中表示?

我正在Swift中创建一个NSManagedObject子类,当我创建一个类型为Int,Float或Double的可选属性时,我得到一个错误(也许是其他我没试过的).

@NSManaged var number: Float? //error:Property cannot be marked @NSManaged because its type cannot be represented in Objective-C
@NSManaged var anotherNumber: Float //no error
@NSManaged var array: NSArray? //no error
@NSManaged var anotherArray: Array<String>? //no error
Run Code Online (Sandbox Code Playgroud)

Objective-C中可以表示哪些可选类型?当我使用Swift数组或字符串时(以及当我没有使用Optional Int或Double时),为什么不出现错误?

objective-c optional nsmanagedobject swift

21
推荐指数
1
解决办法
1万
查看次数

为什么我的Swift类的扩展在定义文件之外不可见?

我的CoreData模型有一个Xcode生成的NSManagedObject类.

@objc(SomeClass) class SomeClass : NSManagedObject { /* ... */ }
Run Code Online (Sandbox Code Playgroud)

它在名为"SomeClass.swift"的文件中定义.我想扩展这个类,所以我创建了'SomeClassExtension.swift'.我像这样定义扩展:

extension SomeClass {
    class func typeMethod1() {}
    func instanceMethod2() {}
}
Run Code Online (Sandbox Code Playgroud)

这些扩展方法可以在此定义文件中使用,但它们在其外部不可见.是什么导致了这个问题?

visibility nsmanagedobject ios swift

21
推荐指数
1
解决办法
9391
查看次数

NSManagedObject和KVO vs Documentation

我有一个自定义NSManagedObject子类,比方说Person.我也UIView注册了-addObserver:forKeyPath:options:context:观察a的各种属性Person,其中一些像"名称"一样持久,而其他属性只是与Core Data无关的KVO兼容的访问器,如"喝酒".

@interface Person : NSManagedObject
{
    BOOL drinking;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, readonly) BOOL drinking;
@end

@implementation Person
@dynamic name;
...
- (void) getDrunk {
    [self willChangeValueForKey: @"drinking"];
    drinking = YES;
    [self didChangeValueForKey: @"drinking"];
}
...
@end
Run Code Online (Sandbox Code Playgroud)

一切正常.每当我发送-getDrunk或设置name属性时,视图都会收到通知.我是一个快乐的人,除非我阅读以下NSManagedObject文件:

+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key
Run Code Online (Sandbox Code Playgroud)

事实1.如果接收器为键值提供键值观察变化通知的自动支持,则为YES,否则为NO.

事实2. NSManagedObject的默认实现为建模属性返回NO,为未建模属性返回YES.

现在我正在努力解析文档中的上述两个事实.检查事实2很简单,类人确实为@"name"返回NO,为@"drink"返回YES.但是,当名称发生变化时,视图如何得到通知?KVO文档清楚地说,

使用自动观察器通知时,没有必要通过调用willChangeValueForKey:和didChangeValueForKey来对属性进行更改:当通过键值编码和符合键值编码的方法改变属性时.

因此,如果Person从+automaticallyNotifiesObserversForKey:@"name" 返回NO ,那么我似乎必须手动将名称设置器包装will/didChangeValueForKey:为KVO才能工作.但是,KVO工作正常.我错过了什么?是什么在点NSManagedObject的覆盖+automaticallyNotifiesObserversForKey:和记录它,如果它似乎没有改变标准的志愿行为? …

cocoa core-data key-value-observing nsmanagedobject

20
推荐指数
1
解决办法
4818
查看次数

NSURagedObjectModel initWithContentsOfURL返回nil,尽管modelURL有效

我的NSManagedObjectModel返回nil,尽管路径正确.

        NSString *modelKey = [NSString stringWithFormat:@"/%@/Model", name];
    NSString *modelPath = [((Configuration *)[Configuration shared]) stringEntry:modelKey];
    NSURL *modelURL = nil;
    if ( ! [modelPath contains:@"://"] ) {
        modelPath = PathForBundleResource( modelPath );
        modelURL = [NSURL fileURLWithPath:modelPath];
    }
    NSManagedObjectModel *m = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Run Code Online (Sandbox Code Playgroud)

NSString*PathForBundleResource(NSString*relativePath)

    NSString* resourcePath = [[NSBundle mainBundle] resourcePath];
return [resourcePath stringByAppendingPathComponent:relativePath];
Run Code Online (Sandbox Code Playgroud)

我重置了模拟器,做了一个干净的构建,但没有任何帮助.

我是iPhone编程的新手(特别是核心数据).

非常感谢任何帮助.

编辑:我编辑了有关xcdatamodeld文件的原始帖子.它最初没有正确连接,但现在它仍然存在同样的问题.

编辑2:显然,xcdatamodel的名称在链接后对xcdatamodel的名称有一些变化.它现在正在运作.感觉很蠢.不知道如何删除这个问题.

iphone nsmanagedobject

20
推荐指数
1
解决办法
8764
查看次数

在Core数据iOS中设置自动增量

我正在使用Core Data,并希望将auto_increment ID设置为唯一的字段之一.是否可以使用核心数据在iOS中设置auto_increment?任何人都可以帮我一个如何实现这个的小例子?

下面是我在数据库中插入记录的代码.在第一个字段"id"中,我想将其设置为auto_increment而不是手动插入它.

- (NSManagedObjectContext *)managedObjectContext {
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}

NSManagedObjectContext *context = [self managedObjectContext];

// Create a new managed object
NSManagedObject *newObj = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:context];

[newObj setValue:[NSNumber numberWithInt:userId] forKey:@"id"];
[newObj setValue:theFileName forKey:@"Name"];
Run Code Online (Sandbox Code Playgroud)

core-data auto-increment nsmanagedobject ios xcode5

20
推荐指数
1
解决办法
2万
查看次数

NSManagedObjectContext无法删除其他上下文中的对象

我有两个实体,每个实体都在自己的UITableView部分显示.

我已启用编辑功能,允许用户通过向右滑动来删除行.这适用于第一个实体,但是当我尝试删除第二个实体中的对象时,我收到此错误:

An NSManagedObjectContext cannot delete objects in other contexts
Run Code Online (Sandbox Code Playgroud)

我得到了错误所说的内容,但我看不出它在这里是如何适用的.我使用对上下文的保留引用来创建,获取和删除数据库中的所有对象,因此我确信只有一个上下文.我也没有使用多线程.知道会发生什么吗?

iphone core-data nsmanagedobject

19
推荐指数
2
解决办法
9803
查看次数

使用CoreData,如果我有@dynamic属性,我可以像@synthesized一样覆盖它的getter吗?(懒惰实例化)

使用CoreData我创建了一个实体,然后将其子类化为自己的文件,其中包含@propertys,然后在.m文件中包含@dynamic部分.

当我希望某些东西具有某个值时,如果它从未被设置过,我总是使用惰性实例化,如下所示:

- (NSString *)preview {
    if ([self.body length] < 200) {
        _preview = self.body;
    }
    else {
        _preview = [self.body substringWithRange:NSMakeRange(0, 200)];
    }

    return _preview;
}
Run Code Online (Sandbox Code Playgroud)

但是如何使用@dynamic属性执行此操作?如果我做同样的事情,它说_preview是一个未声明的属性,但它在.h文件中.懒惰实例化它我做什么不同?

core-data objective-c nsmanagedobject ios

19
推荐指数
2
解决办法
6456
查看次数

使用swift 3和Xcode 8 beta对NSManagedObject进行子类化

我开始尝试使用swift 3和Xcode 8 beta的Core数据.当我尝试从核心数据模型生成NSManagedObject子类并在编辑器菜单中创建NSManagedObject子类...选项时,Xcode 8 beta生成三个文件,其中一个是_COREDATA_DATAMODELNAME_ + CoreDataModel.swift,其中包含以下内容:

import Foundation
import CoreData

___COREDATA_DATAMODEL_MANAGEDOBJECTCLASSES_IMPLEMENTATIONS___
Run Code Online (Sandbox Code Playgroud)

此外,此文件的内容显示两个警告:

Expressions are not allowed at the top level.
Use of unresolved identifier '___COREDATA_DATAMODEL_MANAGEDOBJECTCLASSES_IMPLEMENTATIONS___'
Run Code Online (Sandbox Code Playgroud)

有没有人面临同样的问题?这个新文件的含义是什么?

谢谢

core-data nsmanagedobject swift3 xcode8

19
推荐指数
1
解决办法
2万
查看次数