-
-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Retain cycle setting delegate to valueFormatter #1854
Comments
Why using self directly, shouldn't it be |
I tried weakSelf prior to posting this and that did not make a difference, which makes sense. After dismissing, self ends up staying in memory. I confirmed this using memory graph on xcode. If I remove that line mentioned previously, the retain cycle goes away and self deallocates as it should. |
I'd create a separate class for value formatter instead of using self. |
@edalford11 If I understand correctly, the retain chain is: Using another object rather than self is also workaround, but I think the point here is we figure out why weakSelf won't work. I don't think it's the library bug? Since the |
I don't think assigning weak properties makes a difference because those properties can still be captured strongly. I triple checked this to make sure and yes using the weakSelf pattern did not make a difference here. I navigated to AxisBase.swift and changed fileprivate var _axisValueFormatter: IAxisValueFormatter? to weak fileprivate var _axisValueFormatter: IAxisValueFormatter? The retain cycle is now gone. Appreciate it guys! This library is free and it does way more than most charting libraries do that are paid so keep up the good work. |
There are three ways to solve this problem:
|
Thanks @Huang-Libo . Regarding the other issue you referenced, setting a weak property to valueModifier does not work. The first way is the best way (Setting the delegate definition to weak) because it is known that all delegates definitions should be weak references. Setting the delegate to weak when dismissing the view controller is bad design as these kinds of things should be cleaned up in memory automatically. |
@edalford11
|
@Huang-Libo yes that got rid of the retain cycle for me. |
Scratch that. That caused some other regressions. The problem: When wanting to implement IAxisValueFormatter via the delegate pattern it needs to be a weak reference. When it needs to be set to a custom value formatter like the DefaultAxisValueFormatter, it needs to be a strong reference. With this approach it seems like the best way to avoid the retain cycle is to do what @algrid said and create separate class for value formatter. That being said, there is definitely a retain cycle issue when using a controller to conform to the IAxisValueFormatter protocol and that probably shouldn't be allowed in the first place with this design implementation. |
@edalford11 |
@Huang-Libo yes I believe its a simple design flaw that wasn't caught earlier but nothing a quick refactor can't fix. I do believe a simple class to fill in the labels with should come with the library (The way @algrid suggested). I'll submit a pull request. Looks like 3.0.1 came out with IndexAxisValueFormatter, which is solves this problem. |
@edalford11 I am still struggling why weakSelf won't work.. As |
@liuxuan30 Yes it was the first thing I tried and it did not work. And it shouldn't work. The delegate is a STRONG property. It doesn't matter if you give it a weak value, the property itself is still going to capture it strongly. |
@edalford11 if you use
|
@hotuanlinh89 yes I agree. @edalford11 if you use weak and not using your 'self'(view controller?), the axis labels will not appear. I just tested my PR, it has issues using weak. Just like you mentioned earlier "That caused some other regressions." Besides, I don't know why you said it's not work of using weakSelf, even if aAxis holds valueFormatter as strong, if valueFormatter is actually a weakSelf, it should work.. Just like we use weakSelf in a block, right? the |
@liuxuan30
|
@Huang-Libo your code is not valid |
It's a clerical error, I mean
Maybe I need use another class as formatter. |
I think we can use
This code can work well in my project. |
@Huang-Libo yes using a separate class would solve that, however, towards your weakSelf plus cell, it's obscure to say 'weakSelf' work or not. In my opinion, it should work, since it's just like a block usage |
It has issues using weak because you designed it to be a both a delegate and a pointer to a class in memory. One causes a retain cycle and the other works. Changing it to weak solves the retain cycle but make it not work when using a class as the value. This is overall a design flaw. It really should be designed such that there is only one way to set the formatter that won't cause any retain cycles. |
I'm not sure if I am wrong in the first place, but so far no one gives a solid proof that 'weakSelf' does not work. In my opinion, weakSelf should work, just like how we use it in a block. Until we can say using weakSelf is completely different in valueFormatter than block, it's hardly a design flaw. |
@liuxuan30 assigning a weak variable to a property that is defined as strong (in this case valueFormatter) does not automatically make that property weak. That is why the weak pattern does not work in this design. I have tried it myself including others in this thread. It does not work. |
Just migrated to 3.0. Good to go except I can't get rid of a retain cycle that seems to be coming from IChartAxisValueFormatter
Chart set up below
Using the IChartAxisValueFormatter delegate to set the xaxis labels
when I take out
The retain cycle goes away.
I'm not familiar enough with swift to know what exactly is causing this as I generally use obj-c but it does look like there is some block passing when digging into the valueFormatter code.
The text was updated successfully, but these errors were encountered: