在加载外部脚本之后执行class ViewController: UIViewController {
override func viewDidLoad() {
firstButton.tag = 1
secondButton.tag = 2
thirdButton.tag = 3
}
func goToNextVC(buttonTag: Int) {
let vc = SecondVC()
vc.buttonTag = buttonTag
self.navigationController.push(vc, animated: true)
}
// action for all buttons if he just only send tag
func buttonsDidTap(_ sender: Any) {
goToNextVC(buttonTag: sender.tag)
}
}
是否有好处或问题?
好处可能是GC释放了一些内存?
在som编辑后,以下代码应足以引起注意。
查看评论。
class SecondVC: UIViewController {
var buttonTag: Int?
override func viewDidLoad() {
if buttonTag != nil {
switch buttonTag:
case 0:
// ...
}
}
}
我不知道Javascript是如何做到的,或者它是否可以免费供浏览器使用,但是如果在将其插入dom后在闭包中保留了很多大脚本,则应该通过垃圾回收将其删除。手动收集器(如果不是自动完成的话(最好需要引用w3c才能知道所有兼容的浏览器都可以)
答案 0 :(得分:1)
是的,将属性设置为null
确实有益于GC。这样做会删除元素(包含在DOM中)对处理程序函数的引用,并且鉴于它可能是对该函数的唯一引用,因此它使该函数有资格进行收集。但是,除非该函数是对保留大量内存的变量的封闭,否则不太可能产生很大影响。
您可能还想从回调中的DOM中删除s
元素,使其也可以垃圾回收。
答案 1 :(得分:0)
是的,s.onload = null
很有用,并且会垃圾收集!
As of 2019, it is not possible to explicitly or programmatically trigger garbage collection in JavaScript。这意味着它会在需要时收集。
尽管将there is cases设置为null
可能会更早执行GC(但不要触发它)。
从2012年开始,所有现代浏览器都附带mark-and-sweep垃圾收集器。
它基于 reachability :
从全局上下文无法访问的每个对象都将被删除
标记扫掠会在返回,重新分配或将其设置为null 时定期发现并删除对象。同样,如今也不需要对无法通过任何变量访问的内容进行递归设置为null-无论如何,它都是通过 mark-and-sweep 收集的。
现在转到有问题的代码...
在第一行中,我们看到s
和document.head
的子项指向相同的document.createElement('script')
。当函数返回并从调用堆栈中删除闭包时,其声明的变量s
也将被删除。尽管s
引用的值仍然不是垃圾回收,因为它仍然可以通过document
到达。
所以..不需要s = null
,因为删除变量后指针仍然会清除,但是仍然引用脚本onload
属性,因为<script onload>
是孩子从document.head
可以访问的DOM window
中!
callback
的内容可能可以访问,但是这里毫无疑问。
如果浏览器足够聪明,可以在内部设置s.onload = null
怎么办?我们首先尝试在第一个代码段中将其注释掉,然后在第二个代码段中将其取消注释...
function fetch(src, callback, fail) {
let s = document.head.appendChild(document.createElement('script'));
s.type = "text/javascript";
s.src = src;
s.onload = function() {
callback()
//s.onload = null; //useful?
}
s.onerror = fail
}
fetch("https://stackoverflow.com",
() => {console.log("Execute onload");},
() => {console.log("File not found");})
setTimeout(() => {
console.log(document.head.lastChild.onload)
},1000)
找到的文件不是Javascript,因此执行错误。
onload
已执行但未被删除。该代码显示在日志中!
证明应使用带有s.onload = null
的行,如下所示:
function fetch(src, callback, fail) {
let s = document.head.appendChild(document.createElement('script'));
s.type = "text/javascript";
s.src = src;
s.onload = function() {
callback()
s.onload = null; //useful!
}
s.onerror = fail
}
fetch("https://stackoverflow.com",
() => {console.log("Execute onload");},
() => {console.log("File not found");})
setTimeout(() => {
console.log(document.head.lastChild.onload)
},1000)