阅读my own answer。 我完全理解为什么我们需要为成员/属性提供weakSelf。他们可以创建内存周期。但属性有内存位置。 功能还有内存位置吗?!我的意思是不是一个功能只是在旅途中发生?如果是,那么内存位置类型是否与属性位置有什么不同?
如果我不使用self,我会收到此错误。
在闭包中调用方法'alertFunc'需要明确的'self'。至 使捕获语义显式化
与以下略有不同:
在闭包中引用属性'window'需要明确的'self'。至 使捕获语义显式化
我的代码如下:
let another = UIAlertAction(title: "Log", style:UIAlertActionStyle.Default){action in
logAction ()
}
private func logAction () {
print("health")
}
答案 0 :(得分:2)
来自于我从聚会上知道的iOS书呆子
tl; dr你需要将self用于实例方法,但 class 方法不需要它。一个类可能有很多实例,但它只能有一个自身声明(也包含它的类型/类/静态函数)。
为什么会出现错误1:请注意alertFunc
可能有对某个属性的引用。
可能是:
private func logAction () {
print("someProperty = \(self.someProperty)")
}
因此,在这种情况下,您最终会引用一个属性。
为什么会出现错误2:即使您的函数中没有对self
的引用,仍然因为您将其作为实例方法编写,自我就是隐式传递。但是,我们没有看到!
实例方法实际上只是一个函数的语法糖,它接受第一个参数的实例,它是自动传递的。
在幕后,它可能看起来像这样的东西:
private func alertFunc (_ instance: MyType) {
print("someProperty = \(instance.someProperty)")
}
// and actually the call to it *may* look something like this:
MyType.someFunc(self)
我们从未看到自我被传递!这是一种欺骗我们的语法糖。
因此,如果你的方法不在内部使用self(即不以任何方式依赖于实例的状态)那么实际上最好使它成为static/type/class method或自由函数。
替代方案1:使用免费功能。
class someClass {
...
}
func freeFunc {
print("Hi this is a free function, written outside the scope of any class...")
}
然后在你的关闭中,你使用freeFunc()
替代方案2:使用班级功能。
class someClass {
...
class private func alertFunc() {
print("Hi this was a class function, see the class at the beginning of the func definition")
}
}
然后在你的关闭中,你使用yourClassName.alertFunc()
但是,为什么类函数不会创建内存循环而实例函数呢? 我很高兴你问:
例如mehtods,对于您接触到的每个实例,都有一个 new 内存位置并生成一个 new 内存周期,该周期将持续解除分配。
对于类方法,每次接触类/类型方法时,都会触及相同类/类型方法,并且在持久化该类方法时,您将不会一遍又一遍地创建它,它只创建一次并完成!
在objective-C(和C ++)类型方法中:
当应用程序启动时,系统可以相当安全地预先分配所有指令 将那些类型的方法与它们的类指针一起放入内存中 因此,几乎没有任何开销一遍又一遍地调用那些 我想很快就会做同样的事情
答案 1 :(得分:2)
当您撰写logAction()
时,它隐含地表示self.logAction()
。 (在某些实例上调用方法;当您不指定时,它默认为self
。)因此,您在闭包内使用self
,这意味着闭包捕获self
,以及它是否捕获强或弱参考都会影响内存管理。