class Example {
var prop: Int = 0
var closureProp: (() -> ())?
var funcProp: (() -> ())?
func test() {
func otherInline() {
prop = 2 // no error (!?)
}
closureProp = {
prop = 3 // error, self should be used etc
}
funcProp = otherInline
}
}
Both create a retain cycle, however, only for the second one we get an error (only mentioning that we should use self, nothing about the retain cycle) Am I missing something here? I'm wondering what are the ownership rules in both cases
I donโt know the answer to the question but I assume that you could technically outsource the nested function into a type method which will capture self implicitly anyway and youโre still allowed to create a strong ref. cycle.
class Example {
var prop: Int = 0
var closureProp: (() -> ())?
var funcProp: (() -> ())?
func test() {
func otherInline() {
prop = 2 // no error (!?)
}
closureProp = {
prop = 3 // error, self should be used etc
}
funcProp = otherMethod
}
func otherMethod() {
prop = 2
}
}
@Avi I'm not sure what you mean by "doesn't hold state" but these are both retain cycles examples: closure retains self, self retains closure. @all There's actually a substantial difference between a inner func and a normal method, best illustrated by this example:
class Example {
var innerFunc: () -> ()
init() {
func helloInner() {
print("hello")
}
innerFunc = helloInner
}
func hello() {
print("hello")
}
}
let example = Example()
let hello = Example.hello
//hello() // will not work, missing the first argument, self
hello(example)() // will work
var innerFunc: (() -> ())? = nil
while true {
let otherExample = Example()
innerFunc = otherExample.innerFunc
break
}
innerFunc?() // will work
As you can see, the hello static func requires the first parameter to be self, which makes sense. However, innerFunc doesn't, and since it works without crashing when called in the last line, it means it retains self (in the last line otherExample is out of scope, although not necessarily dealloc'ed)
Now, this leads me to believe that every time we use inner funcs like these, we'll have a retain cycle, and there's nothing we can do about it. Based on what you guys have already said, this seems to be a compiler bug/shortcoming.