ChartsOrg / ChartsOrg/Charts

Crash when opening a view with a chart in it, and closing it before it finished rendering

Open
#4,947 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
28k
Forks
6k
PR merge metrics
No merged PRs in 30d

Description

* [X] I've read, understood, and done my best to follow the [*CONTRIBUTING guidelines](https://github.com/jjatie/Charts/blob/master/CONTRIBUTING.md).

## What did you do?

Create a view with a chart on it. Open view and close the view quickly again.

## What did you expect to happen?

No crash

## What happened instead?

The following crash happens:

- Fatal error: Attempted to read an unowned reference but the object was already deallocated

## Charts Environment

**Charts version/Branch/Commit Number:**
4.1.0
**Xcode version:**
14.0.1
**Swift version:**
5
**Platform(s) running Charts:**
iOS 16.0
**macOS version running Xcode:**
12.6.1

## Demo Project

Sorry, I have no demo project. But it's easy to reproduce, and I know what the issue is.

In `ViewPortJob.swift`, you have defined `viewPortHandler`, `view` and `transformer` as `unowned`. Now, if a `viewPortJob` is running, it's using an animation. At some point there will be an animation and `animationUpdate` will be called. When the view is destroyed while the animation is still running, the `unowned` objects have been deallocated when `animationUpdate` or `animationEnd` is called. And then the function references an `unowned` object that has been deallocated.

Solution is simple. Make the objects `weak` instead of `unowned`, and use `guard let` to return if they were unallocated, or grab a strong reference for the duration of the function.

```
open class ViewPortJob: NSObject
{
internal var point: CGPoint = .zero
internal weak var viewPortHandler: ViewPortHandler?
internal var xValue = 0.0
internal var yValue = 0.0
internal weak var transformer: Transformer?
internal weak var view: ChartViewBase?
...
```

```
guard let view = view,
let transformer = transformer,
let viewPortHandler = viewPortHandler else {
return
}

var pt = CGPoint(
x: xValue,
...
```

etc. where necessary.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.