carekit-apple/CareKit

fatal error when deleting task

Closed this issue · 15 comments

Hello,

I am sometimes getting a fatal error when I delete a task from the store.

Fatal error: Attempted to read an unowned reference but object 0x600000226eb0 was already deallocated2022-03-20 10:24:12.633048+1030 Myapp[2120:63794] Fatal error: Attempted to read an unowned reference but object 0x600000226eb0 was already deallocated

It crashes in the file OCKTaskController.swift in the fetchAndObserveEvents function
Specifically on this line of code

self.subscribeTo(tasks: viewModelUpdate.tasks, query: eventQuery)

Thanks for spotting this issue! We'll do some investigating.

Does this reproduce every time a task is deleted or just occasionally?

Hi, thanks for the reply.
No seems to happen randomly, and my code to delete the task is the same every time.

@magray which branch are you using? main or stable? I'm not seeing the line you referenced above:

self.subscribeTo(tasks: viewModelUpdate.tasks, query: eventQuery)

After some investigation, I suspect the underlying issue is the general use of unowned self throughout the task controller. Some of the publishers in that class dispatch their work onto a new queue asynchronously, which does mean that when the work actually starts it's not guaranteed that self is still hanging around in memory. You may encounter that issue if the task view controller you're presenting is dismissible. Attempting to delete a task, then quickly dismissing the view controller might result in a crash. Is that scenario akin to your setup?

The next step will be to audit each use of unowned self and determined whether we want to instead capture a strong or weak reference.

Hi yes using the main branch
https://github.com/carekit-apple/CareKit/blob/a612482e4ba4f28d4c75129c0a9b70ca23098bd6/CareKit/CareKit/Shared/Task/Controller/OCKTaskController.swift#L233

my setup is using a swiftUI list, with ObservableObject class view model. the VM will ask the store for OCKAnyTask which presents them in a published struct array. The struct includes the task ID, when the user swipes to delete a row, a func is called in the VM to use the ID to grab that OCKTask from the store then deletes it.

Hello @gavirawson-apple,

I'm also facing the same issue but in my case, it happens when I use OCKSimpleTaskViewController class. I've created a custom class inherited from OCKSimpleTaskViewController, the app crashes when I try to delete the tasks.

It works fine if I change OCKSimpleTaskViewController to OCKInstructionsViewController or OCKGridTaskViewController.

Please advise.

Thanks,

  • Majid S.

@gavirawson-apple Can we have a fix for this please. My app is ready to go but I don't really want to release it knowing
that a user could encounter this bug at any time. Not a good look for my app.

@magray Are you comfortable sharing relevant bits of your view model code? I'm most interested in the parts where it interacts with the task controller.

A crash at the line that was highlighted above is strange, and is perhaps an indicator of a different issue than I had originally thought. self is used in the line prior, it's odd the crash doesn't occur there. If you can, sharing the crash logs will also help us dig deeper and find the issue.

@majidsaleem105 sharing the bits of your code that interact with the task controller may help as well. OCKSimpleTaskViewController and OCKInstructionsTaskViewController are nearly identical, I would expect the crash to occur in each class if it is happening in one. Are you seeing the crash happen at the same line of code as @magray?

@magray Are you comfortable sharing relevant bits of your view model code? I'm most interested in the parts where it interacts with the task controller.

Sure, is there somewhere I can send to you privately maybe?

A crash at the line that was highlighted above is strange, and is perhaps an indicator of a different issue than I had originally thought. self is used in the line prior, it's odd the crash doesn't occur there. If you can, sharing the crash logs will also help us dig deeper and find the issue.

I can include crash logs.

If you're comfortable, sharing a private gist may be the easiest route.

Hi @gavirawson-apple

You can review the code on the following https://gist.github.com/majidsaleem105/eaeb31ce3f6d776fe55f0b06cd32600a.
We've created UISegmentControl to segregate activities and surveys. If you see the surveys and then try to delete the surveys tasks, it prompts the following error:

image

Assuming this crash is coming from the OCKTaskController, can you try going in there and changing the capture of self from unowned to weak at the crash site? Let me know if that fixes the issue.

Hi @gavirawson-apple,

You're right. This crash was coming from the OCKTaskController. I made the suggested changes, and it fixed the issue. The app isn't crashing on deleting the tasks now.

Thanks a lot for your kind help!

Best Regards,

  • Majid S.

Glad it's fixed! If you're interested, consider contributing the fix to the main branch, I'm sure it will help many others.

Hi Sorry to reopen this,
@majidsaleem105 can you share the code of where you fixed this please
Thanks