gpt4 book ai didi

core-data - iOS 13.4 CoreData SwiftUI 应用程序在设备上崩溃并显示 "EXC_BREAKPOINT (code=1, subcode=0x1f3751f08)"

转载 作者:行者123 更新时间:2023-12-02 10:20:42 25 4
gpt4 key购买 nike

一个非常简单的 CoreData 应用程序:下面提供了所有代码。

  • 使用 CoreData 模板单一 View 应用启动。
  • 2 个实体,每个实体都有一个字符串属性:消息(标题)和帖子(名称)

包含的导航 View

  • 消息列表的导航链接
  • 导航链接到帖子列表

每个链接的ListView(消息/帖子)都有

  • 将项目添加到列表的按钮
  • 用于从列表中删除所有项目的按钮

现在,当您在模拟器(任何 iOS 13.x 版本)上运行此应用程序时,所有内容都会按上述描述的预期运行。

但是在运行 iOS 13.4 的设备上

  • 点按“消息”
  • 创建/删除消息工作正常,SwiftUi View 会立即更新。
  • 点击“返回”
  • 再次点击“消息”。虽然创建/删除消息仍然可以正常工作:调试器现在显示警告:“环境中的上下文未连接到持久存储协调器:NSManagedObjectContext:0x280ed72c0
  • 轻按“帖子”==> 应用程序因 EXC_BREAKPOINT 崩溃(代码=1,子代码=0x1f3751f08)

您也可以先从帖子开始该过程。然后消息 ListView 上也会发生同样的崩溃。

我坚信这是一个 iOS 13.4 错误,因为类似的代码在 Xcode 11.3/iOS 13.3 上运行良好。

有人知道这个问题的修复或解决方法吗?

这里是完整项目的链接:Full Xcode Project

内容 View :

import SwiftUI
import CoreData


struct MessageList: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Message.entity(), sortDescriptors: [])
var messages: FetchedResults<Message>

var body: some View {
List() {
ForEach(messages, id: \.self) { message in
Text(message.title ?? "?")
}
}
.navigationBarItems(trailing:
HStack(spacing: 16) {
Button(action: deleteMessages) {
Image(systemName: "text.badge.minus")
}
Button(action: addMessage) {
Image(systemName: "plus.app")
}
}
)
}
func addMessage() {
let m = Message(context: moc)
m.title = "Message: \(Date())"
try! moc.save()
}
func deleteMessages() {
messages.forEach {
moc.delete($0)
}
}
}

struct PostList: View {
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Post.entity(), sortDescriptors: [])
var posts: FetchedResults<Post>

var body: some View {
List {
ForEach(0..<posts.count, id: \.self) { post in
Text(self.posts[post].name ?? "?")
}
}
.navigationBarItems(trailing:
HStack(spacing: 16) {
Button(action: deletePosts) {
Image(systemName: "text.badge.minus")
}
Button(action: addPost) {
Image(systemName: "plus.app")
}
}
)
}
func addPost() {
let p = Post(context: moc)
p.name = "Post \(UUID().uuidString)"
try! moc.save()
}
func deletePosts() {
posts.forEach {
moc.delete($0)
}
try! moc.save()
}
}


struct ContentView: View {
@Environment(\.managedObjectContext) var moc

var body: some View {
NavigationView {
VStack(alignment: .leading){
NavigationLink(destination: MessageList()) {
Text("Messages")
}.padding()
NavigationLink(destination: PostList()) {
Text("Posts")
}.padding()
Spacer()
}
}.navigationViewStyle(StackNavigationViewStyle())
}
}

struct ContentView_Previews: PreviewProvider {
static let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
static var previews: some View {
ContentView()
.environment(\.managedObjectContext, moc)
}
}

模型截图:

Model

SceneDelegate(未对模板进行更改,为了完整性而提供):

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = ContentView().environment(\.managedObjectContext, context)

if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}

func sceneDidDisconnect(_ scene: UIScene) {}
func sceneDidBecomeActive(_ scene: UIScene) {}
func sceneWillResignActive(_ scene: UIScene) {}
func sceneWillEnterForeground(_ scene: UIScene) {}
func sceneDidEnterBackground(_ scene: UIScene) {
(UIApplication.shared.delegate as? AppDelegate)?.saveContext()
}
}

AppDelegate(未对模板进行更改,为了完整性而提供):

import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {}

// MARK: - Core Data stack

lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "Coredata134")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()

func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}

最佳答案

更新 iOS 14.0(测试版 1):

此问题似乎已在 iOS 14 上得到解决。

<小时/>

我也相信这是一个错误。

您现在可以通过在 ContentView 的 NavigationLinks 中再次设置环境变量来解决此问题:

NavigationLink(destination: MessageList().environment(\.managedObjectContext, moc)) {
Text("Messages")
}.padding()
NavigationLink(destination: PostList().environment(\.managedObjectContext, moc)) {
Text("Posts")
}.padding()

编辑:

刚刚注意到,这种解决方法至少有一个严重的负面影响:如果目标 View 中的 @FetchRequest 使用 sortDescriptor 并且目标 View 本身包含一个 NavigationLink(例如,到 DetailView),则修改包含的属性一旦新的属性值导致新的排序顺序,DetailView 中的 sortDescriptor 中的值将导致 DetailView 被弹出并再次推送。

为了证明这一点:

a) 将名为“value”的 Integer 16 类型的新属性添加到核心数据模型中的消息实体。

b) 更新 func addMessage() 如下:

func addMessage() {
let m = Message(context: moc)
m.title = "Message: \(Date())"
m.value = 0
try! moc.save()
}

c) 将以下结构添加到 ContentView.swift

struct MessageDetailList: View {
@ObservedObject var message: Message
var body: some View {
Button(action: {
self.message.value += 1
}) {
Text("\(message.title ?? "?"): value = \(message.value)")
}
}
}

d) 更新结构体 MessageList 中的 ForEach,如下所示:

ForEach(messages, id: \.self) { message in
NavigationLink(destination: MessageDetailList(message: message).environment(\.managedObjectContext, self.moc)) {
Text("\(message.title ?? "?"): value = \(message.value)")
}
}

e) 将 MessageList 中的 @FetchRequest 替换为:

@FetchRequest(entity: Message.entity(), sortDescriptors: [NSSortDescriptor(key: "value", ascending: false)])

运行代码并点击“消息”。创建三条消息,然后点击第三条消息。在详细信息 View 中,点击按钮。这会将该消息的 value 属性增加到 1,从而将获取结果重新放到 MessageList 上,这将触发详细列表的再次弹出和推送。

enter image description here

关于core-data - iOS 13.4 CoreData SwiftUI 应用程序在设备上崩溃并显示 "EXC_BREAKPOINT (code=1, subcode=0x1f3751f08)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60843114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com