【问题标题】:Core Data iOS app crashes when getting the contextCore Data iOS 应用程序在获取上下文时崩溃
【发布时间】:2014-01-05 08:44:49
【问题描述】:

我将 Quickblox 用于我的聊天应用程序,并使用核心数据来存储消息历史记录。

当我登录聊天时,我重新发送了上次发送失败的消息。 (即我从 Core Data 获取消息并获取未发送的消息)

有时它可以工作,但有时应用程序在辅助方法(用于获取核心数据上下文)上崩溃:

+ (NSManagedObjectContext *)context {
    return ((AppDelegate *)[UIApplication sharedApplication].delegate).managedObjectContext;
}

我没有为 App Delegate 更改任何内容,它只是一个普通的启用 CoreData 的 AppDelegate:

@interface AppDelegate : UIResponder <UIApplicationDelegate, QBActionStatusDelegate, QBChatDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;


@end

这就是我在 DBHelper 类中检索消息历史记录的方式

+ (NSMutableArray *)fetchMessagesWithSenderID:(NSString *)userID {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Message" inManagedObjectContext:[DBHelper context]]; //the app crashes here, inside [DBHelper context]
    [fetchRequest setEntity:entity];

    NSPredicate *pred = [NSPredicate predicateWithFormat:@"sender.userID = %@", userID];
    [fetchRequest setPredicate:pred];


    NSError *error;

    NSMutableArray *fetchedObjects = [[DBHelper context] executeFetchRequest:fetchRequest error:&error].mutableCopy;
    return fetchedObjects;
}

日志:

2014-01-05 16:32:05.365 Chat[1517:60b] completedWithResult: <QBMRegisterSubscriptionTaskResult: 0x14e955e0>
2014-01-05 16:32:05.366 Chat[1517:60b] error: (
    "Invalid provisioning profiles. You have to use valid Provisioning Profiles for your project"
)
2014-01-05 16:32:06.549 Chat[1517:180f] QBChat/didConnect
2014-01-05 16:32:07.913 Chat[1517:4103] -[QBChat xmppStreamDidAuthenticate:] -> user: 573782, supportsStartTLS: 1, isSecure: 0
2014-01-05 16:32:07.913 Chat[1517:60b] chatDidLogin
2014-01-05 16:32:07.916 Chat[1517:60b] -[QBMGetTokenPerformer managedObjectContext]: unrecognized selector sent to instance 0x14d48800
(lldb) 

【问题讨论】:

    标签: ios core-data crash chat quickblox


    【解决方案1】:

    -[QBMGetTokenPerformer managedObjectContext]:无法识别的选择器发送到实例 0x14d48800

    这一行意味着您已经在 QBMGetTokenPerformer 类的对象上调用了 managedObjectContext 方法,但它无法识别该方法。

    从您问题中的代码和您显示的屏幕截图来看,这不应该发生 - 我不知道对应用程序委托的调用如何有时返回一个不相关的对象 -我唯一一次看到这种情况发生是由于内存管理问题,但应用程序委托实际上是一个单例,因此它的内存无法重新分配。

    我只能建议您向您的应用程序添加一个异常断点 - 尽管看起来您已经有了一个。您也许可以将您的方法分成单独的行,以便您可以看到每一行发生了什么。

    【讨论】:

    • 内存管理问题可能会导致 AppDelegate 在内存中被覆盖,因此仍有可能,但不太可能。
    • QBMGetTokenPerformer 来自 QuickBlox,但我认为它不会调用任何核心数据方法。 (QuickBlox 只是一个聊天框架,不需要 Core Data)
    • @OMGPOP - 我意识到,这就是问题所在。不知何故,您为 managedObjectContext 请求了错误的对象,因此在请求您的应用程序委托时,您必须返回错误的对象。
    【解决方案2】:

    尝试将所有 CoreData 逻辑从 AppDelegate 移到单独的单例中:

    *.h 文件:

    @interface CoreDataService : NSObject
    
     +(instancetype)instance;
     - (void)saveContext;
    
    @end
    

    *.m 文件:

    @implementation CoreDataService
    
    @property (readonly, strong, nonatomic) NSManagedObjectContext
    *managedObjectContext;  
    @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;    
    @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator
    *persistentStoreCoordinator;
    
     - (void)saveContext{   
     ... 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-29
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      相关资源
      最近更新 更多