Swift:弱参考存储&嵌套块/闭包

时间:2016-03-18 16:35:43

标签: swift automatic-ref-counting

我希望嵌套一个块/闭包,而另一个进程完成主线程,如此

typealias FirstBlock = (jsonDictionary:NSDictionary?,errorCode:NSString?) -> Void

typealias SecondBlock = (complete:Bool?,errorCode:NSString?,dictionary:NSDictionary?) -> Void
  • 控制器

        func startPoint {
    
            SomeNetworkManager.sharedInstance.firstProcess(self.someDictionary) { (complete, errorCode, dictionary) -> Void in
    
            // I want to get here with a strong reference to these objects in this class only
            print(complete,errorCode,dictionary)
        }
    }
    
  • SomeNetworkManager

    func firstProcess(dictionary:NSDictionary?, completion:SecondBlock?) {
    
    let request = HTTPRequest.init(requestWithPath:"path", httpMethod: .post) { (jsonDictionary, errorCode) -> Void in
    
        let organisedDictionary:NSMutableDictionary = NSMutableDictionary() 
        // Some processing of the json into a new dictionary
    
        dispatch_async(dispatch_get_main_queue()) {
    
            if errorCode == nil {
    
                completion!(complete:true,errorCode:nil,dictionary:organisedDictionary)
            }
            else {
    
                completion!(complete:false,errorCode:errorCode,dictionary:nil)
            }
        }
    }
    
    request.postDataDictionary = refinementsDictionary as! NSMutableDictionary
    request.request()
    
    }
    
  • 的HTTPRequest

    var processBlock:FirstBlock?
    
    init(requestWithPath path:NSString, httpMethod method:HTTPMethod, andProcessBlock block:FirstBlock) {
    
        super.init()
    
        self.requestURL = NSURL(string:path as String);
        self.responseData = NSMutableData()
        self.processBlock = block
    
        switch (method) {
         case .post:
            self.httpMethod = kPost
            break;
         case .put:
            self.httpMethod = kPut
            break;
         default:
            self.httpMethod = kGet
            break;
        }
    
    }
    
    // An NSURLConnection goes off, completes, I serialise the json and then...
    
    func completeWithJSONDictionary(jsonDictionary:NSDictionary) {
    
        self.processBlock!(jsonDictionary:jsonDictionary,errorCode:nil)
        self.processBlock = nil
    }
    

我遗漏了一些关于ARC保留周期的基本原因,因为每当其中一个被称为内存泄漏时我就已经看过了...我已经看了一下 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html 没有快乐..我认为Defining a Capture List是正确的区域,但至于存储块以及如何定义它我不知道我做错了什么。

1 个答案:

答案 0 :(得分:1)

很有可能,你得到保留周期,因为完成块引用了HttpRequest(可能是通过调用对象),引用了完成块,如:

class HttpReference {
    let completion : ()->()

    init(completion:()->()) {
        self.completion = completion
    }
}

class Owner {
    var httpReference : HttpReference?

    func someFunction() {
        httpReference = HttpReference() {
            print(self.httpReference)
        }
    }
}

有两种方法可以通过使用unowned引用或使用weak引用来打破周期,两者都非常相似,在这种情况下,规范将是使用通过改变来无限地提及自我:

func someFunction() {
    httpReference = HttpReference() { [unowned self] in
        print(self.httpReference)
    }
}

现在,self未被保留,从而打破了保留周期。