【问题标题】:Lifetime of NSString created within a case statement在 case 语句中创建的 NSString 的生命周期
【发布时间】:2013-01-16 14:49:27
【问题描述】:

我有一个使用 ARC 支持 DynamoDB 的核心数据的 iOS 程序。

在其中我有一个声明了以下类的数据模型:

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


@interface Track : NSManagedObject

@property (nonatomic, retain) NSString * trackId;

@end

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

#import "Track.h"


@implementation Track

@dynamic trackId;

@end

然后我有一个类创建 ManagedObject 的实例并像这样持久化它:

NSString *trackId = @"ABC123";

Track *track = (Track*)[NSEntityDescription insertNewObjectForEntityForName:@"Track" inManagedObjectContext:context];
track.trackId=trackId;

NSError *error;
if (![appDelegate.managedObjectContext save:&error])
{
    NSLog(@"error: %@", error);
}

这按预期工作。但是,如果我使用开关来更改 trackId 的值,如下所示:

for (int i=0; i<1; i++) {
    NSString *trackId;
    switch (i) {
        case 0:
            trackId = @"XYZ789";
            break;
    }

    Track *track = (Track*)[NSEntityDescription insertNewObjectForEntityForName:@"Track" inManagedObjectContext:context];
    track.trackId=trackId;
}

NSError *error;
if (![appDelegate.managedObjectContext save:&error])
{
    NSLog(@"error: %@", error);
}

然后我得到以下异常:

2013-01-16 14:44:00.013 DjTest2[2351:c07] XYZ789
2013-01-16 14:44:00.014 DjTest2[2351:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'
*** First throw call stack:
(0x183e012 0x1663e7e 0x18c10de 0x107c9bf 0x39799 0x1ff5e4 0xc7831 0xf533c 0x3411 0x68c817 0x68c882 0x5dba25 0x5dbdbf 0x5dbf55 0x5e4f67 0x5a8fcc 0x5a9fab 0x5bb315 0x5bc24b 0x5adcf8 0x268bdf9 0x268bad0 0x17b3bf5 0x17b3962 0x17e4bb6 0x17e3f44 0x17e3e1b 0x5a97da 0x5ab65c 0x258d 0x24b5)
libc++abi.dylib: terminate called throwing an exception

我认为在使用 ARC 的变量范围/保留方面存在一些我不知道的问题,其中 NSString 文字是在开关范围内创建的,但我找不到对它的任何引用。

有谁知道造成这种情况的根本原因是什么,以及在无法执行此类操作的情况下如何有效地处理持久化大量对象?

注意:我已经提到支持 DynamoDB 以确保完整性,但在尝试调用 AWS 之前会引发此异常。

【问题讨论】:

  • 可能有助于设置异常断点以查看它实际被抛出的位置,而不是让它冒泡。 stackoverflow.com/questions/4961770/…
  • 问题不在你的switch,应该没问题。尽管将指针设置为空不是很健康。你应该通过写来初始化你的字符串:NSString *trackId = nil;(但同样,这只是一个建议,不是崩溃的原因)
  • AWSPersistenceDynamoDBIncrementalStore 中的 gainPermanentIDsForObjects 引发了异常,但这是验证输入到 kev/value 映射中的键的地方。我还没有检查是否支持 SQL DB,但如果 NSString 是在 switch 语句之外分配的,那么保存工作正常,我看不出这可能是一个原因。
  • @Levi 同意,上面的代码用于演示目的。

标签: ios core-data switch-statement


【解决方案1】:

恐怕我在上面的代码示例中误入歧途了,为了清楚起见,我在输入 SO 时更新了该示例。

实际问题不在于它在 switch 语句中,而是我正在使用的一些真实键中有空格,我假设这些键受到 Core Data 的限制,因为 DynamoDB 没有这样的限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-16
    • 2022-06-14
    • 2013-04-06
    • 2017-04-21
    • 1970-01-01
    相关资源
    最近更新 更多