2015-06-04 2 views
1

У меня есть следующий код для создания наблюдаемого свойства для привязки данных. Это в работах, поэтому я не уверен, какова будет окончательная реализация, и я все еще довольно новичок в Swift.Слабая ссылка на закрытие в Swift

class Observable<T> { 
    typealias Observer = T -> Void 

    var value: T { 
     didSet { 
      for observer in self.observers { 
       observer?(self.value) 
      } 
     } 
    } 

    var observers: [Observer?] = [] 

    init(_ val: T) { 
     self.value = val 
    } 
} 

Я хотел бы сохранить слабые ссылки на закрытие наблюдателя. Я не хочу полагаться на клиента, чтобы убедиться, что закрытие слабо/не используется, прежде чем передавать его через список захвата. Тем более, что на данном классе может быть много наблюдаемых свойств.

Возможно ли, чтобы ссылки на замыкание были слабыми в моем классе Observable?

UPDATE:

Я нашел несколько ресурсов, которые я думаю, поможет мне добиться того, чего я хочу:

Make self weak in methods in Swift

специально,

func methodPointer<T: AnyObject>(obj: T, method: (T) ->() -> Void) -> (() -> Void) { 
    return { [unowned obj] in method(obj)() } 
} 

Следующая ссылка относится к вышеуказанному ответу stackoverflow и идет более подробно:

http://blog.xebia.com/2014/10/09/function-references-in-swift-and-retain-cycles/

и это двустороннее связывание пример:

http://five.agency/solving-the-binding-problem-with-swift/

конкретно,

class BondBox<T> { 
    weak var bond: Bond<T>? 
    init(_ b: Bond<T>) { bond = b } 
} 

где слушатель обернут в классе под названием Бонд, который слабо ссылки в BondBox.

ответ

2

Можно ли сделать ссылки закрытия слабых в моем классе наблюдаемых

No. только экземпляры класса могут быть отнесены к через слабые ссылки в Swift, а функция не является экземпляром класса. (И не только они должны быть экземплярами класса, они должны быть необязательными, обертывая экземпляр класса.)

Есть некоторые довольно очевидные пути вокруг этого, или курс - простейший из которых является классом-оболочкой. Но я на самом деле не рекомендую это в этой ситуации, потому что вы не убедили меня в том, что здесь требуются слабые ссылки на функции. Помните, что слабая ссылка на объект, к которому нет сильной ссылки, мгновенно потеряет ссылку и будет указывать на нуль. Я не могу поверить, что это то, чего ты хочешь. Я думаю, что ты лаешься по неправильному дереву здесь.

+0

В конечном счете, я хочу, чтобы время жизни наблюдателя не зависело от времени жизни наблюдаемых классов. Разве это не проблема? – lintmouse

+0

Конечно, это проблема. Но это не имеет никакого отношения к тому, что ссылка на слабость. Это связано с тем, что ссылка на наблюдаемый экземпляр внутри слабой функции. Только вызывающий может сказать «слабое», как вы сказали; нет волшебного пути вокруг него (конечно, сделать ссылку на слабую функцию не волшебным способом вокруг нее). – matt

+0

Или вы могли бы очень разумно сделать 'self.value' слабым. Итак, если это произойдет, вы просто не будете называть наблюдателей. Довольно просто. Но, возможно, это не решит проблему, извините. – matt

0

Слабые/сильные для управления памятью объектов, поэтому применяются только для переменных ссылочных типов (то есть типов, которые указывают на объекты). Типы функций в Swift не являются ссылочными типами, и поэтому не имеет смысла говорить о слабых/сильных для своих переменных.

Плюс, на самом деле у вас фактически нет переменных типа функции в вашем коде (кроме середины итерации). У вас просто есть переменная типа массива. Даже в Objective-C вы можете только отмечать переменные как слабые или сильные, а не значения, которые хранятся внутри других вещей.

И если бы вы написать, что вы пишете в Objective-C, вы бы хотите «Observable» иметь сильные ссылки на затворы. В противном случае, кто еще имел бы сильную ссылку на закрытие?

+0

Так может ли объект Observable сохранить другой объект живым, просто с помощью замыкания, которое передал другой объект? Мне кажется, что ссылки, зафиксированные в закрытии, сделают это возможным. Если это так, то это проблема, которую я пытаюсь решить. В .NET существует шаблон слабых событий и обычно применяется к привязке данных. Попытка выяснить, является ли это проблемой и в Swift. – lintmouse

+0

@dustmouse: Почему бы вам не подумать о том, как это сделать в Objective-C. Если вы сделаете это в Objective-C, он будет содержать ссылки на закрытие, а поставщик закрытия решает, имеет ли закрытие слабые или сильные ссылки на другие вещи. Не обязательно, чтобы Наблюдатель решал эти вещи; для пользователя «Observable» должно быть предусмотрено, чтобы конструкция крышки соответствовала ее потребностям. – newacct

+0

В идеале, не каждый слушатель должен был бы реализовать слабый шаблон наблюдателя, и его можно было бы управлять в центральном месте, таком как WeakEventManager in. NET. Но я, вероятно, не думаю об этой проблеме быстрый/obj-c-способ, и это то, что я повесил. – lintmouse

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

  • Нет связанных вопросов^_^