Comments (12)
the test step could expose memory leak are as follow:
- We have two ViewController embed in
UINavigationController
:ViewControllerA
andViewControllerB
- push to
ViewControllerB
- use
Each
like demo doing, atViewControllerB
'sviewDidLoad
function.
override func viewDidLoad() {
super.viewDidLoad()
Each(1).seconds.perform {
print("second passed")
return false
}
}
- Pop
ViewControllerB
. - Timer is still running, because of the each instance wasn't free and
deInit
not been called. - We got a memory leak.
from each.
For now, a simple workaround could be: store the Each
instance in your UIViewController
and call the stop()
method in the deinit
as below:
class BViewController: UIViewController {
let timer = Each(1).seconds
deinit {
timer.stop()
}
override func viewDidLoad() {
super.viewDidLoad()
timer.perform { [weak self] in
print("Timer called")
self?.dismiss(animated: true, completion: nil)
return .continue
}
}
}
from each.
Here is a way to resolve this issue in Objective-C: PSWeakProxy
But invoke it case dependence.
I'm trying to find out a way with pure swift.
from each.
@DeveloperPans I'm actually working on it on feature/memory-leak-fix
branch
For now I succeeded to make a sort of weak timer. The only requirement is that the object has to hold a strong reference to the Each
instance, like the example below:
class BVC: UIViewController {
let timer = Each(1).seconds
override func viewDidLoad() {
super.viewDidLoad()
timer.perform {
print("tiemer called")
return .continue
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.dismiss(animated: true, completion: nil)
}
}
This works nicely and there is no need to call the stop()
when the BVC.deinit
is called
from each.
great!
from each.
So, as I explained in the post up here, with this fix, you are not able anymore to create a timer in your method scope by only typing the simple syntax (see below) because the controller has to keep a reference to it.
Each(1).seconds.perform {
// do something
return .continue
}
I found an another solution with a colleague of mine, which allows you to do it again. But Each
needs the owner reference to check whether it's been deallocated in the mean time to stop the timer execution, so a prototype of the implementation will be
Each(1).seconds.performOn(self) {
// do something
return .continue
}
What do you think guys? I can even try to wrap this method call up in a NSObject
extension.
from each.
Actually I'm thinking about this issue really a lot. I decided that the memory leak should stay there: unfortunately it's the default behavior of NSTimer
class provided by Apple. There are some workarounds to keep your code free from memory leaks using Each
Workaround 1
In case you don't want to declare a property that holds the Each
reference, create a normal Each
timer in your method scope and return .stop/true
whenever the owner
instance is nil
Each(1).seconds.perform { [weak self] in
guard let _ = self else { return .stop }
print("timer called")
return .continue
}
90% of closures will call self
somehow, so this isn't so bad
Workaround 2
In case the first workaround wasn't enough, you can declare a property that holds the Each
reference and call the stop()
function whenever the owner
is deallocated
final class ViewController: UIViewController {
private let _timer = Each(1).seconds
deinit {
_timer.stop()
}
override func viewDidLoad() {
super.viewDidLoad()
_timer.perform {
// do something and return. you can check here if the `self` instance is nil as for workaround #1
}
}
}
@DeveloperPans I'll update the README
with these examples
from each.
May be paste Workaround 2 to README could help more people and this discuss perform its values. Do you think so?
from each.
I think for now it's ok until someone will find a good solution for it.
Each
is cool because the developer can simply use it. All the fixes I found make the interface not easy as it is now.
from each.
Less global variables are better… I think.
So I vote performOn
: )
Best regards!
潘晟
Shawn Pan
Team Leader
http://shengpan.net
在 2016年10月24日,21:26,dalu93 [email protected] 写道:
So, as I explained in the post up here, with this fix, you are not able anymore to create a timer in your method scope by only typing because the controller has to keep a reference to it.
Each(1).seconds.perform {
// do something
return .continue
}
I found an another solution with a colleague of mine, which allows you to do it again. But Each needs the owner reference to check whether it's been deallocated in the mean time to stop the timer execution, so a prototype of the implementation will beEach(1).seconds.performOn(self) {
// do something
return .continue
}
What do you think guys? I can even try to wrap up this method call in a NSObject extension.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub #4 (comment), or mute the thread https://github.com/notifications/unsubscribe-auth/AIgE4MHXZT8c3zzf2cS0_cfewIORtpYYks5q3LH1gaJpZM4Kd7Kf.
from each.
I'm gonna implement that method too. In this way the developer can easily choose his implementation @DeveloperPans
from each.
I just merged the new method on develop
. It will be released soon in the version 1.1.1
from each.
Related Issues (9)
- Value for milliseconds multiplier is wrong HOT 1
- Carthage compatibility
- pod install error HOT 2
- Add `Disposable` concept
- Timer stops during scrolling HOT 1
- Add you to my RSS feed? HOT 2
- Make the `perform` closure return type more readable HOT 2
- 'seconds' is inaccessible due to 'internal' protection level HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from each.