核心数据仅在存储的最后一个子记录上存储指向父记录的链接

时间:2011-06-09 17:11:48

标签: core-data xcode4 relationships

我有一个使用XCode 4创建的核心数据模型正在做一些奇怪的事情。我有一个名为ProbeObj的实体,它与第二个名为SmokeObj的实体有一个已定义的关系。在图中,我已经在ProbObj上创建了关于ProbeToSmoke的关系,并且在SmokeObj上,我创建了关系作为SmokeToProbe并将其设置为与ProbeObj上定义的关系的反向关系。我生成了.h&这两个对象的.m文件,我将它们包含在我创建的类中,以处理数据的插入。他们在这里:

//
//  SmokeObj.h
//  Stoker Monitor
//
//  Created by NCGrimbo on 6/3/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class BlowerObj, CurBlowerObj, CurProbeObj, ProbeObj, StokerObj;

@interface SmokeObj : NSManagedObject {
@private
}
@property (nonatomic, retain) NSDate * dtEnd;
@property (nonatomic, retain) NSDate * dtStart;
@property (nonatomic, retain) StokerObj * SmokeToStoker;
@property (nonatomic, retain) ProbeObj * SmokeToProbe;
@property (nonatomic, retain) CurProbeObj * SmokeToCurProbe;
@property (nonatomic, retain) CurBlowerObj * SmokeToCurBlower;
@property (nonatomic, retain) BlowerObj * SmokeToBlower;

@end

//
//  SmokeObj.m
//  Stoker Monitor
//
//  Created by NCGrimbo on 6/3/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "SmokeObj.h"
#import "BlowerObj.h"
#import "CurBlowerObj.h"
#import "CurProbeObj.h"
#import "ProbeObj.h"


@implementation SmokeObj
@dynamic dtEnd;
@dynamic dtStart;
@dynamic SmokeToStoker;
@dynamic SmokeToProbe;
@dynamic SmokeToCurProbe;
@dynamic SmokeToCurBlower;
@dynamic SmokeToBlower;

@end


//
//  ProbeObj.h
//  Stoker Monitor
//
//  Created by NCGrimbo on 6/3/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class SmokeObj;

@interface ProbeObj : NSManagedObject {
@private
}
@property (nonatomic, retain) NSDate * dtDataRead;
@property (nonatomic, retain) NSNumber * fCurTemp;
@property (nonatomic, retain) NSNumber * fHighTemp;
@property (nonatomic, retain) NSNumber * fLowTemp;
@property (nonatomic, retain) NSNumber * fTargetTemp;
@property (nonatomic, retain) NSNumber * nAlarmType;
@property (nonatomic, retain) NSNumber * nCtrlAlrmType;
@property (nonatomic, retain) NSString * sBlower;
@property (nonatomic, retain) NSString * sID;
@property (nonatomic, retain) NSString * sUserAssignedName;
@property (nonatomic, retain) SmokeObj * ProbeToSmoke;

@end

//
//  ProbeObj.m
//  Stoker Monitor
//
//  Created by NCGrimbo on 6/3/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "ProbeObj.h"


@implementation ProbeObj
@dynamic dtDataRead;
@dynamic fCurTemp;
@dynamic fHighTemp;
@dynamic fLowTemp;
@dynamic fTargetTemp;
@dynamic nAlarmType;
@dynamic nCtrlAlrmType;
@dynamic sBlower;
@dynamic sID;
@dynamic sUserAssignedName;
@dynamic ProbeToSmoke;

@end

我的代码从网站收集数据,解析它,然后将记录添加到ProbObj表中。 SmokeObj的数据被传递到程序的这一部分并存储为self.SmokeForThisRun。这是处理此问题的代码,删除了不相关的部分:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    NSError *error;
    NSArray *chunks = [responseString componentsSeparatedByString: @"{"];
    [responseString release];
    NSArray *details;
    NSArray *arrTheData;
    Boolean bIsSensor = false;
    Boolean bIsBlower = false;
    Boolean bStokerFound = false;
    NSRange textRange;


    for (int i = 0; i < [chunks count]; i++){

        if(!bStokerFound){
        }
        else{
            if ((!bIsBlower) && (!bIsSensor)){
            }
            else{
                if (bIsSensor){
                    //Set the probe data that is fixed
                    ProbeObj *newProbe = [NSEntityDescription insertNewObjectForEntityForName:@"ProbeObj" inManagedObjectContext:[Common managedObjectContext]];
                    newProbe.dtDataRead = [NSDate date];
                    //newProbe.nSmokeID = [NSNumber numberWithInt: 0];
                    NSLog(@"Setting ProbeToSmoke = %@", self.SmokeForThisRun);
                    newProbe.ProbeToSmoke = self.SmokeForThisRun;

                    //Parse the sensor information then save the data  {Parse code removed.}

                    //Save the Probe Record
                    if (![[Common managedObjectContext] save:&error]) {
                        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
                        UIAlertView *saveError = [[UIAlertView alloc]initWithTitle:@"Error Saving the Probe Data." message:[error localizedDescription] delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];
                        [saveError show];
                        [saveError release];
                    }
                    else{   
                       NSLog(@"Data saved for %@", newProbe);
                    }
                }
            }
        }
    }
}

此代码每1分钟调用一次,以便从网站获取最新信息。

我遇到的问题是,当我通过代码或SQLLite数据库查看器应用程序查看数据时,唯一具有SmokeObj集的记录是最后一条记录。例如,如果SmokeObj = 1并且我收集ProbeObj数据3次,则只有最后一个ProbeObj将具有SmokeObj = 1.其他两个将具有SmokeObj的空值。如果我只收集1个ProbeObj,那么它将具有正确的SmokeObj值。无论我收集数据1次还是100次,都会出现问题。只收集的最后一条记录具有正确的SmokeObj。

非常感谢任何帮助。

-NCGrimbo

1 个答案:

答案 0 :(得分:0)

您的SmokeObj.SmokeToProbe关系是一对一设置的。这意味着SmokeObj的任何单个实例都只能与ProbeObj的另一个单个实例建立关系。

因此,当您完成循环时,首先将SmokeObj中的self.SmokeForThisRun分配给ProbObj引用的第一个创建的newProb。然后,下一次循环时,您将关系更改为newProb现在持有的第二个实例,依此类推。只有最后创建的newProb引用的实例实际上以关系集的值结束。

解决方案是将SmokeObj.SmokeToProbe更改为多对多关系,以便相同的SmokeObj obj可以与几个'ProbeObj`相关联。

(顺便说一下,你应该遵循实体/类和属性的命名约定。实体和类名的首字母有资本,但属性没有。例如SmokeObj.SmokeToProbe应该是SmokeObj.smokeToProbe。它会使你的代码更易于他人阅读。)