变量不是CFString错误

时间:2011-04-23 01:30:14

标签: objective-c cocoa-touch ios4 core-data memory-management

嘿fellas,在通过调试器运行时我看到以下内容出现第二时间它设置变量(时间戳和校验和是通过这个方法一个接一个地设置的,它在没有时工作正常DataFeedManager存在,但在再次返回时它会在设置校验和时崩溃:)

debug screen shot

以下是感兴趣的功能:

//sets specified attribute to the passed in value while ensuring that only one instance of the DataFeedManager exists
-(void)setItemInDFMWhilePreservingEntityUniquenessForItem:(attribute)attr withValue:(id)value {
    SJLog(@"CoreDataSingleton.m setItemInDFMWhilePreservingEntityUniquenessForItem");
    NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription 
                                   entityForName:@"DataFeedManager" inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSUInteger numEntities = [[self managedObjectContext] countForFetchRequest:fetchRequest error:&error];

    if (numEntities == NSNotFound) { // ERROR
        //...

    } else if (numEntities == 0) {
        DataFeedManager *dfm = (DataFeedManager *)[NSEntityDescription insertNewObjectForEntityForName:@"DataFeedManager" 
                                                                                inManagedObjectContext:[self managedObjectContext]];
        if (attr == checksumAttr) { //BLOCK OF INTEREST
            NSString *tempVal = [[NSString alloc] initWithString:value];
            [dfm setLastUpdateCheckSum:[NSString stringWithString:tempVal]]; 
        } else if (attr == timeStampAttr) {
            [dfm setTimeStamp:value];
        }
    } else { // more than zero entities
        if (numEntities == 1) {
            NSArray *fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
            if (attr == checksumAttr) { //BLOCK OF INTEREST
                NSString *tempVal = [[NSString alloc] initWithString:value];
                [[fetchedObjects objectAtIndex:0] setLastUpdateCheckSum:[NSString stringWithString:tempVal]]; //crashes at this line, after successfully going through the previous BLOCK OF INTEREST area
            } else if (attr == timeStampAttr) {
                [[fetchedObjects objectAtIndex:0] setTimeStamp:value];
            }
        } else { // ERROR: more than one entity
            //...
        }
    } // else more than zero entities
    [fetchRequest release];
}//setItemInDFMWhilePreservingEntityUniquenessForItem:withValue:

我已经用//BLOCK OF INTEREST条评论标记了感兴趣的区域,并指出了发生崩溃的行(向右滚动以查看它!)。以下是控制台的错误读数:

2011-04-22 17:18:10.924 Parking[26783:207] CoreDataSingleton.m setItemInDFMWhilePreservingEntityUniquenessForItem
2011-04-22 17:18:10.924 Parking[26783:207] -[__NSCFDictionary length]: unrecognized selector sent to instance 0xac34850
2011-04-22 17:18:10.970 Parking[26783:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary length]: unrecognized selector sent to instance 0xac34850'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x011a0be9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x012f55c2 objc_exception_throw + 47
    2   CoreFoundation                      0x011a26fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x01112366 ___forwarding___ + 966
    4   CoreFoundation                      0x01111f22 _CF_forwarding_prep_0 + 50
    5   Foundation                          0x00c4d1e1 -[NSPlaceholderString initWithString:] + 162
    6   Foundation                          0x00c562c2 +[NSString stringWithString:] + 72
    7   Parking                             0x0000e4d4 -[CoreDataSingleton setItemInDFMWhilePreservingEntityUniquenessForItem:withValue:] + 774
    8   Parking                             0x00008bb4 -[DataUpdater allDataRetrievedWithSuccess:withError:] + 225
    9   Parking                             0x0000952e -[DataUpdater dataDownloadCompleted:forFunc:withData:withError:] + 769
    10  Parking                             0x00010bb5 -[DataRetriever finish] + 432
    11  Parking                             0x00010e75 -[DataRetriever connectionDidFinishLoading:] + 36
    12  Foundation                          0x00c61172 -[NSURLConnection(NSURLConnectionReallyInternal) sendDidFinishLoading] + 108
    13  Foundation                          0x00c610cb _NSURLConnectionDidFinishLoading + 133
    14  CFNetwork                           0x0348e606 _ZN19URLConnectionClient23_clientDidFinishLoadingEPNS_26ClientConnectionEventQueueE + 220
    15  CFNetwork                           0x03559821 _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 293
    16  CFNetwork                           0x03559b0f _ZN19URLConnectionClient26ClientConnectionEventQueue33processAllEventsAndConsumePayloadEP20XConnectionEventInfoI12XClientEvent18XClientEventParamsEl + 1043
    17  CFNetwork                           0x03484e3c _ZN19URLConnectionClient13processEventsEv + 100
    18  CFNetwork                           0x03484cb7 _ZN17MultiplexerSource7performEv + 251
    19  CoreFoundation                      0x0118201f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    20  CoreFoundation                      0x010e019d __CFRunLoopDoSources0 + 333
    21  CoreFoundation                      0x010df786 __CFRunLoopRun + 470
    22  CoreFoundation                      0x010df240 CFRunLoopRunSpecific + 208
    23  CoreFoundation                      0x010df161 CFRunLoopRunInMode + 97
    24  GraphicsServices                    0x01414268 GSEventRunModal + 217
    25  GraphicsServices                    0x0141432d GSEventRun + 115
    26  UIKit                               0x0004e42e UIApplicationMain + 1160
    27  Parking                             0x00002698 main + 102
    28  Parking                             0x00002629 start + 53
)
terminate called after throwing an instance of 'NSException'

我认为它与充分复制字符串有关(不能设置我不拥有的字符串到商店)。我试过放[value copy]以及&value(看到这种事情对别人有用,所以我想我会试一试)无济于事。我现在的方法不应该充分取得字符串的所有权吗?我仍然无法弄清楚我做错了什么。任何帮助赞赏。谢谢!

2 个答案:

答案 0 :(得分:5)

最佳猜测(部分基于this answer)是当您第二次调用该方法时,或者可能value时,您将value作为NSDictionary传递。第二次是id类 - 从这段代码片段中不清楚为什么你的方法采用NSString类型的参数然后轻率地将它视为{{1}}的一个实例,但是这可能是问题的一部分。

答案 1 :(得分:1)

请注意,您的-setItemInDFMWhilePreservingEntityUniquenessForItem:withValue:在其第二个参数(类型id)中接受任意对象。

在方法中,您可以:

NSString *tempVal = [[NSString alloc] initWithString:value];

除非value是Objective-C字符串,否则会导致程序崩溃。实际上,您的崩溃日志显示,在该特定执行中valueNSDictionary。您需要确保valueNSString

另请注意,由于您使用了tempVal,因此您拥有了分配给+alloc的字符串。别忘了释放那个字符串。