2016-08-17 3 views
3

Есть ли способ указать «клиенту» определенного метода, что параметр закрытия будет сохранен?Swift Указывает, что параметр закрытия сохраняется

Например, имея следующий код:

import Foundation 

typealias MyClosureType =() -> Void 

final class MyClass { 

    private var myClosure: MyClosureType? 

    func whatever(closure: MyClosureType?) { 
     myClosure = closure 
    } 
} 

Любой может начать использовать этот класс и переходя затворов к методу whatever без какой-либо идеи о том, если она фактически сохраняется или нет. Это подвержено ошибкам и может привести к утечке памяти.

Например, «клиент» делает что-то вроде этого, не будет никогда высвобождены

final class MyDummyClient { 

    let myInstance = MyClass() 

    func setUp() { 
     myInstance.whatever { 
      self.whateverHandler() 
     } 
    } 

    func whateverHandler() { 
     print("Hey Jude, don't make it bad") 
    } 
} 

Вот почему я хотел бы знать, если есть способ предотвратить этот тип ошибок. Некоторый тип paramater, который я мог бы добавить к определению моего метода whatever, который дает клиенту подсказку о необходимости ослабления во избежание утечек.

ответ

2

Независимо от того, выполняется ли параметр закрытия или не выполняется экранирование, это некоторая индикация для вызывающего абонента можно ли его сохранить. В частности, a не -определяющий закрывающий параметр не может быть сохранен вызовом функции.

Per SE-0103, не избежать закрытия (в настоящее время отмечается @noescape) будет по умолчанию в Swift 3, и вы должны будете написать @escaping, если вы хотите сохранить закрытия, поэтому ситуации, как это станет немного более очевидным ,

В противном случае нет никакой языковой функции, которая вам поможет. Вам придется решить эту проблему при разработке и документации API. Если это что-то вроде обработчика, я бы порекомендовал свойство obj.handler = { ... } или метод вроде obj.setHandler({ ... }) или obj.addHandler({ ... }). Таким образом, при чтении кода вы можете легко сказать, что закрытие сохраняется из-за = или set или add.

(На самом деле, при компиляции Obj-C, Clang explicitly looks for methods named set...: or add...: при определении того, чтобы предупредить пользователь о сохранении циклов. Возможно подобные диагностики могут быть добавлены к Swift компилятору в будущем.)

0

С конкретный случай, когда вы представляете закрытие, - это единственное, что будет сохранено, поэтому, если вы правильно добавите [слабое я] к вашему закрытию, когда вы его вызываете, не должно быть никаких проблем.

Я не уверен, в какой проблеме вы пытаетесь защитить, но вы также можете использовать делегирование (протоколы), а не закрытие.

Смежные вопросы