这是Apple的文档中的一个示例:
class HTMLElement { let name: String let text: String? lazy var asHTML: Void -> String = { if let text = self.text { return "<\(self.name)>\(text)\(self.name)>" } else { return "<\(self.name) />" } } init(name: String, text: String? = nil) { self.name = name self.text = text } deinit { print("\(name) is being deinitialized") } }
我理解为什么这个闭包属性会导致强引用周期,我知道如何解决它.而且我不打算这么说.
让我困惑的是以下代码:
var heading: HTMLElement? = HTMLElement(name: "h1") let defaultText = "some default text" heading!.asHTML = { // confusing, this closure are supposed to retain heading here, but it does not return "<\(heading!.name)>\(heading!.text ?? defaultText)\(heading!.name)>" } print(heading!.asHTML()) heading = nil // we can see the deinialization message here, // it turns out that there is not any strong reference cycle in this snippet.
据我所知,从Swift文档和我自己的Objective-c经验来看,变量heading
将被闭包捕获,因此应该引起一个强大的参考周期.但事实并非如此,这让我很困惑.
我还写了一个这个例子的Objective-c对应物,它确实引起了我预期的强引用周期.
typedef NSString* (^TagMaker)(void); @interface HTMLElement : NSObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *text; @property (nonatomic, strong) TagMaker asHTML; @end @implementation HTMLElement - (void)dealloc { NSLog(@"%@", [NSString stringWithFormat:@"%@ is being deinitialized", self.name]); } @end
;
HTMLElement *heading = [[HTMLElement alloc] init]; heading.name = @"h1"; heading.text = @"some default text"; heading.asHTML = ^ { return [NSString stringWithFormat:@"<%@>%@%@>", heading.name, heading.text, heading.name]; }; NSLog(@"%@", heading.asHTML()); heading = nil; // heading has not been deinitialized here
任何提示或指南将不胜感激.
因为,在后一种情况下
Swift 闭包有一个强大的参考,heading
而不是heading
那个点的实例
在图像中,它显示如下
如果我们按设置打破红线heading = nil
,那么参考圆就会被打破.
更新开始:
但是,如果你没有将航向设置为零,那么仍然有一个参考圆圈,就像我在上面发布的图像一样.你可以像这样测试它
func testCircle(){ var heading: HTMLElement? = HTMLElement(name: "h1") let defaultText = "some default text" heading.asHTML = { return "<\(heading.name)>\(heading.text ?? defaultText)\(heading.name)>" } print(heading.asHTML()) } testCircle()//No dealloc message is printed
更新结束
我还编写了下面的测试代码来证明闭包没有对内存中的实例进行强有力的引用
var heading: HTMLElement? = HTMLElement(name: "h1") var heading2 = heading let defaultText = "some default text" heading!.asHTML = { // confusing, this closure are supposed to retain heading here, but it does not return "<\(heading!.name)>\(heading!.text ?? defaultText)\(heading!.name)>" } let cloureBackup = heading!.asHTML print(heading!.asHTML()) heading = HTMLElement(name: "h2") print(cloureBackup())//some default text
所以,测试代码的图像是
你会看到游乐场的日志
some default text
some default text
没有找到任何关于这个的文件,只是从我的测试和理解,希望它会有所帮助