如何在 Objective C 中使用托管对象?

Posted

技术标签:

【中文标题】如何在 Objective C 中使用托管对象?【英文标题】:How to use managed object in Objective C? 【发布时间】:2018-03-28 11:18:05 【问题描述】:

我得到了一个具有特定格式的字符串,它有一个实体名称:@“Entry”。我无法修改字符串。如何访问字符串?我可以访问数组对象,但不能访问内部。如何使用 initWithEntityName?

这是字符串

<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-DC57F484F754> ; data: 
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
),
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536- DC57F484F754> ; data: 
cumulativeTime = 0000;
latitude = “13.067439”
longitude = "80.237617";
type = enrty;
entryName = Chennai;
)

这就是我得到数组的方式。

+(NSArray*) routePlan

NSString* jsonString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Documents/DataJson" withExtension:nil]
                                                        encoding:NSUTF8StringEncoding error:nil];
NSArray* array = [jsonString componentsSeparatedByString:@","];



我需要使用谓词吗?

我需要纬度和对数的值。我可以做“po array[0]”,但不能进入array[0]。

如果我尝试访问纬度,则会出现以下错误。

error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector.
The process has been returned to the state before expression evaluation.

如果我做 po array[0],我得到了下面的结果。

<__NSArrayI 0x7fe093f87160>(
<Entry: 0x600000498c90> (entity: Entry; id: 30506398-1852-433D-B536-DC57F484F754> ; data: 
cumulativeTime = 0000;
latitude = “12.972442”
longitude = "77.580643";
type = enrty;
entryName = Bangalore;
)

【问题讨论】:

您的代码中没有 json。 (尝试在jsonlint.com 上验证) ***.com/questions/41226442/… 这不是 json 'Documents/AircraftDataJson' 是这个 JSON 文件目录吗? @JayachandraA 是的。 【参考方案1】:

首先,你的文件不是json格式的。 现在,当你这样做时:

NSString* aircraftJSONString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Documents/AircraftDataJson" withExtension:nil]
                                                        encoding:NSUTF8StringEncoding error:nil];
NSArray* aircraftJsonFplWaypoints = [aircraftJSONString componentsSeparatedByString:@","];

您实际上是在逗号处拆分文本,这就是为什么您的 aircraftJsonFplWaypoints 包含 2 个对象: 用值输入一个字符串:

<__nsarrayi>((实体:条目; 编号:30506398-1852-433D-B536-DC57F484F754>;数据: 累积时间 = 0000;纬度 = “12.972442” 经度 = “77.580643”;类型=输入; entryName =班加罗尔; )

然后是一个带值的字符串

(实体:条目;id:30506398-1852-433D-B536- DC57F484F754>;数据: 累积时间 = 0000;纬度 = “13.067439” 经度=“80.237617”;类型=输入; entryName =钦奈; )

aircraftJsonFplWaypoints 中的内容是字符串,而不是字典或数组。这会让你无处可去。

您需要做的是使用正则表达式来获取 中的内容。这应该有效:

[^]*

所以我会做类似的事情:

    NSError * error;
    NSString * pattern = @"\\[^\\]*\\";
    NSRegularExpression * regex = [[NSRegularExpression alloc] initWithPattern:pattern
                                                                       options:0
                                                                         error:&error];

    NSArray<NSTextCheckingResult *> * matches = [regex matchesInString:aircraftJSONString options:NSMatchingReportCompletion range:NSMakeRange(0, aircraftJSONString.length)];

    for(NSTextCheckingResult * match in matches)
    
        NSString * substring = [aircraftJSONString substringWithRange:match.range];
        // Remove the bracket
        substring = [substring substringWithRange:NSMakeRange(1, substring.length - 2)];

        // split around the ";" => get the llat/long

        NSArray<NSString *>* parts = [substring componentsSeparatedByString:@";"];
        NSString * latLong = parts[1];

        /* continue to get the longitude and latitude */
    

但我建议使用输入标准,例如,您可以使用 NSJSONSerialisation API 将对象序列化为 json,而不是复制/粘贴 po 输出,这将使存储/检索更加容易。

【讨论】:

【参考方案2】:

您从捆绑文件中获取的数据似乎不是有效的 JSON,它是别的东西。如果是 JSON 数据,那么下面将是获取该数据的方法。

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"DataJson" ofType:@"json"];
NSLog(@"%@",filePath);
NSURL *url = [NSURL fileURLWithPath:filePath];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
if (error == nil)
    NSLog(@"#### JSON object #### %@",jsonObject);
else
    NSLog(@"#### JSON parsing error #### %@",error);

但正如您提到的,您有一个 EntryManagedObject,这意味着您正在尝试从核心数据中获取数据。因此,请确认您如何从 coredata 保存和获取数据。 (提供示例代码)。

如果您认为您的方法是正确的,请尝试打印Entry 对象属性。

   +(NSArray*) routePlan
    
        NSString* jsonString = [NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Documents/DataJson" withExtension:nil]
                                                        encoding:NSUTF8StringEncoding error:nil];
        NSArray* array = [jsonString componentsSeparatedByString:@","];

        [array enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger index, BOOL * _Nonnull stop)
         
             Entry* entry = (Entry*)obj;
             NSLog(@"id is :: %@",entry.id);
             NSLog(@"id is :: %@",entry.data);
         ];
        return nil;
    

【讨论】:

以上是关于如何在 Objective C 中使用托管对象?的主要内容,如果未能解决你的问题,请参考以下文章

在 Objective-C 中释放托管对象

如何用XCode创建Objective-c和C++的混编工程?

如何在Objective C中使用NSData创建json对象?

如何在Objective C中使用解析版本1.12.0加载PFQueryTableViewController中的对象?

C#-C#中的Dispose模式

Objective C 类扩展 - 如何用 readwrite 方法覆盖只读?