【问题标题】:Variable is Not A CFString Error变量不是 CFString 错误
【发布时间】:2011-08-11 07:35:50
【问题描述】:

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

这里是感兴趣的函数:

//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 cmets 标记了感兴趣的区域,并指出了崩溃发生在哪一行(向右滚动查看!)。以下是控制台的错误读数:

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(看到这种东西对其他人有用,所以我想我会试一试)无济于事。我当前的方法不应该充分获得字符串的所有权吗?我仍然无法弄清楚我做错了什么。任何帮助表示赞赏。谢谢!

【问题讨论】:

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


    【解决方案1】:

    最好的猜测(部分基于this answer)是当您第二次调用该方法时,您正在将已释放对象作为value 传递,或者value 可能属于NSDictionary 类在你第二次通过 - 从这段代码 sn-p 中不清楚为什么你的方法接受id 类型的参数,然后愉快地将其视为NSString 的实例,但这可能是问题的一部分。

    【讨论】:

    • 原来我不正确地分配了一个 NSString 的实例,并且在遇到此方法之前它已被释放。谢谢!
    【解决方案2】:

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

    在方法内部,你这样做:

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

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

    另外,请注意您拥有分配给tempVal 的字符串,因为您使用了+alloc。不要忘记释放该字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-25
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多