Переполнение стека, вызванное быстрым закрытием в другом закрытии

UPDATE: эта ошибка подтверждается rdar: // 20931915 и исправлена ​​в Xcode 7 beta 3.


Я нашел странную ошибку, вызванную быстрым закрытием в другом закрытии в сборке отладки. Мой Xcode – версия 6.3.1 с Swift версии 1.2. Вот код:

import Swift class ClosureStackOverflow { private var b: Bool = false private func callClosure1(callback: Void -> Void) { println("in closure 1") callback() } private func callClosure2(callback: Void -> Void) { println("in closure 2") callback() } func call() { callClosure1 { [weak self] in self?.callClosure2 { self?.b = true } } } } let c = ClosureStackOverflow() c.call() 

Вышеприведенный код хорошо компилируется. Однако, если вы вызовете свой метод call (), он будет бесконечно печатать «в закрытии 2» и, в конечном счете, переполнять стек.

Не могли бы вы объяснить, почему вызов одного замыкания внутри другого приведет к этой ошибке?

Благодарю.

Измените свой код на это, и он будет работать

  class ClosureStackOverflow { private var b: Bool = false private func callClosure1(callback: Void -> Void) { println("in closure 1") callback() } private func callClosure2(callback: Void -> Void) { println("in closure 2") callback() } func call() { callClosure1 { self.callClosure2 { self.b = true } } } deinit{ print("deinit") } } 

Кажется, что вы объявляете [weak self] in функции, и это вызывает проблему.

Я также проверяю это на вызов

  let c = ClosureStackOverflow() c.call() 

Он будет выводить

  in closure 1 in closure 2 deinit 

Кажется, что он не вызывает циркулярных ссылок, если вы не используете слабое самосознание

Кроме того, я также тестирую, чтобы изменить функцию на эту

  func call() { callClosure1 { [weak self] in self!.callClosure2 { self?.b = true } } } 

Он также будет работать. Поэтому я думаю, что это может быть ошибка компилятора Quick.

  • OS X Server - бот не может получить источник из репозитория
  • Отключение рук между устройствами iOS и Mac не работает
  • в Xcode имя Bundle в файле info.plist не изменяет имя пакета (имя файла .app)
  • В чем разница между .sqlite и .storedata
  • macOS на VMware не распознает устройство iOS
  • Получение ошибок при установке контейнеров через cocoapods на OS X El Capitan
  • Вернуть версию Apple Clang для NVCC
  • Swift: Как работает $ 0 в Array.forEach?
  • Макрос препроцессора для целей OS X?
  • Является ли XCGLogger потоком безопасным?
  • Удаление устаревших профилей подготовки
  • Давайте будем гением компьютера.