SwiftData EXC_BAD_ACCESS code=1, address=0x8

69 Views Asked by At

I have an app that has one to many relationships and I am trying to load transactions into the app from a text file. As I load the transactions, I randomly hit on EXC_BAD_ACCESS at different times but always on a specific line. The weird part is that it does not crash every time I run the app, it crashes on different runs and on a different transaction but always on the line where I set the category (see below).

I am loading the transactions asynchronously using async/await. I have a progress bar that is updated using the MainActor thread. I am also using an actor to insert the transactions.

I tried to debug with Address Sanitizer, Thread Sanitizer and Zombie objects but did not find anything.

May be I am setting the relationships wrong. I thought it could be a data race issue but did not seem like it - not sure. May be a memory issue and was hoping zombie objects flag would be able to identify but it did not identify anything.

Any direction or help is really appreciated.

 @Model
class Transaction: Hashable {
    @Attribute(.unique) let id = UUID().uuidString
    var date = Date()
    ... different properties
    
//    @Relationship(inverse: \Category.transactions)
    var category: Category?
    
    init(date: Date = Date(), balance: Double = 0.0, category: Category) {
        self.date = date
        self.balance = balance
        self.category = category //<-- always crashes here. I checked that category is a valid address
        category.add(transaction: self)
    }
}

    @Model
    class Category {
        @Attribute(.unique) let id = UUID().uuidString
        var name: String?
//... set properties
        
        @Relationship(deleteRule: .cascade, inverse: \Transaction.category)
        var transactions: [Transaction]? = []
    
        init(name: String? = nil) {
            self.name = name
        }
        
        func add(transaction: Transaction) {
            if var transactions = self.transactions {
                transactions.append(transaction)
            }
        }
        
    }

Reading the text file with transactions

        private func readFile(data: String) async {
    ... parse lines
    // here is where the transaction is created and potentially the issue
           let t = Transaction(date: date, category: category) //<--- trying to set the category in the Transaction.init
           transactions.append(t)
        }
// batching all transactions and inserting category after reading all data
 await actor.insert(category) // insert now

Here is the problem it points to

{
    //    @Relationship(inverse: \Category.transactions)
          @storageRestrictions(accesses: _$backingData, initializes: _category)
    init(initialValue) {
        _$backingData.setValue(forKey: \.category, to: initialValue)
        _asset = _SwiftDataNoType()
    }
    //    @Relationship(inverse: \Category.transactions)
          get {
        _$observationRegistrar.access(self, keyPath: \.category)
        return self.getValue(forKey: \.category)
    }
    //    @Relationship(inverse: \Category.transactions)
          set {
        _$observationRegistrar.withMutation(of: self, keyPath: \.category) {
            self.setValue(forKey: \.category, to: newValue) <---- This is SwiftData code where it is trying to set to newValue triggering the crash
        }
    }
}

Here is where it crashes

@main
struct DataImportWithProgressViewApp: App { <---- Here is where it crashes with Thread1: EXC_BAD_ACCESS (code=1, address=0x8000000000000010)
    let container = try! ModelContainer(
        for: Category.self
    )
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(container)
    }
}
0

There are 0 best solutions below