在managedObjectContext之外的NSManagedObject

时间:2011-03-30 02:30:49

标签: iphone objective-c core-data nsmanagedobject nsmanagedobjectcontext

seen others询问如何在managedObjectContext之外使用NSManagedObject。 似乎每个人都说你不应该这样做,但我无法找到有关该做什么的信息。

我实际上是在尝试使用我的NSManagedObject上设置的数据做两件事。我想要 将它保存到persistentStore,我想将它发送到远程服务器。我的想法是alloc / init 我的NSManagedObject的一个实例,填充它的属性,然后将其传递给那些属性的函数 将被转移到正确实例化的NSManagedObject,然后将其传递给另一个函数 这将负责将数据发送到服务器。

在代码中:( Event是NSManagedObject的子类)

// in my view controller
Event *event = [Event alloc] init];
event.propertyA = @"foo";
event.propertyB = @"bar";

[self logEvent:event];
[self sendEvent:event];

-----------------------------------

// method in view controller 
- (void)logEvent(Event *)event {
    // my thought was to take the event that I manually created, and use it to
    // set the properties on the Event object in the managedObjectContext.

    Event *eventEntity = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:self.managedObjectContext];

    eventEntity.propertyA = event.propertyA;
    eventEntity.propertyB = event.propertyB;
    ...
    [self.managedObjectContext save:&error];
}

- (void) sendEvent:(Event *)event {
    // send exact same event properties to remote server
}

正如您所期望的那样,第二行失败了,我尝试设置propertyA。

我该怎么做?我应该创建一个具有确切的NSObject的vanilla子类 与我的NSManagedObject对象相同的属性/属性?我在问题中提出的解决方案是关于NSInMemoryStoreType的讨论,但是当我真正想要的是一种传递对象的便捷方式时,这似乎有点过分。只是在这种情况下,我的对象是一个NSManagedObject,所以我对它的功能有限。

1 个答案:

答案 0 :(得分:0)

前一段时间我在NSManagedObject上写了一个类别,它创建了托管对象的NSDictionary表示。您可以使用托管对象上下文之外的NSDictionary免责声明:此代码尚未经过全面测试,并且还注意到它只处理托管对象的属性,并且不处理关系

NSManagedObject+CLDAdditions.h
------------------------------

@interface NSManagedObject (CLDAdditions)
- (NSDictionary*)cld_dictionaryRepresentation;
@end

NSManagedObject+CLDAdditions.m
------------------------------

@implementation NSManagedObject (CLDAdditions)

- (NSDictionary*)cld_dictionaryRepresentation
{
    // Create empty dictionary
    NSMutableDictionary *objectDictionary = [NSMutableDictionary dictionary];
    // Set the entity
    [objectDictionary setObject:[[self entity] name] forKey:@"entity"];
    NSDictionary *attributeKeys = [[self entity] attributesByName];
    // Go through each of the attributes and add them to the dictionary
    for (NSString *attributeKey in attributeKeys) {
        id attributeValue = [self valueForKey:attributeKey];
        if (attributeValue) {
            // Supported objects
            if ([attributeValue isKindOfClass:[NSNumber class]] || [attributeValue isKindOfClass:[NSString class]] || [attributeValue isKindOfClass:[NSNull class]] || [attributeValue isKindOfClass:[NSDate class]] || [attributeValue isKindOfClass:[NSData class]] || [attributeValue isKindOfClass:[NSURL class]]) {
                [objectDictionary setObject:attributeValue forKey:attributeKey];
            // Unsupported objects
            } else if ([attributeValue isKindOfClass:[NSDictionary class]] || [attributeValue isKindOfClass:[NSArray class]]) {
                [NSException raise:NSGenericException format:@"Objects of type \"%@\" are not supported as Core Data attributes.", [attributeValue class]];
            // Transformable objects (conforming to NSCoding)
            // TODO: Add support for custom value transformers
            } else if (([[attributeKeys objectForKey:attributeKey] attributeType] == NSTransformableAttributeType) && [attributeValue conformsToProtocol:@protocol(NSCoding)]) {
                NSData *attributeData = [NSKeyedArchiver archivedDataWithRootObject:attributeValue];
                [objectDictionary setObject:attributeData forKey:attributeKey];
            // Otherwise raise an exception
            } else {
                [NSException raise:NSGenericException format:@"Unsupported object type \"%@\". Objects must conform to the NSCoding protocol.", [attributeValue class]];
            }
        }
    }
    return objectDictionary;
}

@end