Xcode 8.1 swift 3 требует вечности, чтобы скомпилировать этот код

У меня есть этот класс в проекте, который раньше использовал Swift 2.3. Когда я перенес проект на Swift 3, компиляция xcode заняла вечность, и я увидел, что он застрял в этом классе. Я не могу собрать весь проект из-за этого класса. Есть ли способ изменить этот класс, чтобы можно было построить проект? Xcode всегда скомпилировал этот фрагмент кода. Если я удалю несколько свойств из MyClass, Xcode снова быстро скомпилируется. Кто-нибудь знает, как решить эту проблему?

import Foundation

class MyClass: NSObject {

    var id: String = ""
    var uid: String = ""
    var uname: String = ""
    var fname: String = ""
    var txt: String = ""
    var hay: Float = 0
    var flag = false
    var long: Double = 0
    var lat: Double = 0
    var altitude: Double = 0
    var course: Double = 0
    var speed: Double = 0
    var lname: String = ""
    var city: String = ""
    var country: String = ""
    var sublocal: String = ""
    var subarea: String = ""
    var thumb: String = ""
    var trash = false
    var date: Double = 0
    var updated: Double = 0
    var furl: String = ""

    func toAnyObject() -> Any {
        return [
            "id": id,
            "uid": uid,
            "uname": uname,
            "fname": fname,
            "txt": txt,
            "hay": hay,
            "flag": flag,
            "long": long,
            "lat": lat,
            "altitude": altitude,
            "course": course,
            "speed": speed,
            "lname": lname,
            "city": city,
            "country": country,
            "sublocal": sublocal,
            "trash": trash,
            "subarea": subarea,
            "thumb": thumb,
            "date": date,
            "updated": updated,
            "furl": furl
        ]
    }
}

person hoang    schedule 05.11.2016    source источник
comment
Наверняка вы хотите аннотировать возвращение toAnyObject() как [String : Any]?   -  person Hamish    schedule 05.11.2016
comment
Я пробовал это, но безуспешно, я заметил, что процесс SourceKitSer использует много CPU, если я пытаюсь скомпилировать этот код PID COMMAND% CPU TIME 2239 SourceKitSer 197.6 00: 35.13 6/2   -  person hoang    schedule 05.11.2016
comment
Я тестировал это на другом Mac с xcode 8.1 swift 3, я создал новый проект только с MyClass, и его компиляция по-прежнему занимает вечность. Очень странный. Вы можете скопировать / вставить мой код и попробовать самостоятельно   -  person hoang    schedule 05.11.2016
comment
Непонятно, что вы хотите от Stack Overflow в этой ситуации. Сообщите об ошибке в Apple! Вы можете подать заявку на bugs.swift.org и рассчитывать на быстрый ответ (по крайней мере, в моем опыте).   -  person matt    schedule 05.11.2016
comment
@matt, я думал, что кто-то в Stackoverflow может знать, как решить эту проблему   -  person hoang    schedule 05.11.2016
comment
Я не совсем понимаю, что вы имеете в виду под исправлением. Вы явно обнаружили ошибку в языке / компиляторе. Что бы исправить? Не пользуетесь Swift? Очевидно, вам следует просто избегать больших словарных литералов того типа, который вы используете. Вам не нужно, чтобы мы вам это говорили!   -  person matt    schedule 05.11.2016
comment
@matt спасибо за ваш комментарий, но он не очень полезен и не решает мою проблему. Просто для пояснения у меня есть этот класс в проекте, который ранее использовал Swift 2.3. Когда я перенес проект на Swift 3, компиляция xcode заняла вечность, и я увидел, что он застрял в этом классе. Итак, проблема, которую нужно исправить, заключается в том, что я не могу собрать весь проект из-за этого класса. Что я хочу исправить, так это изменить этот класс, чтобы можно было построить проект. Если вы не можете помочь, проигнорируйте мой вопрос :)   -  person hoang    schedule 05.11.2016
comment
@hoang в качестве примечания. Вы абсолютно уверены, что они вам нужны как vars? Кажется маловероятным, что вы когда-нибудь обновите id, uid, uname и т.д ... Если они не обновлены, используйте let. Фактически, вы должны использовать let по умолчанию и менять значение на var только в том случае, если компилятор сообщает вам, что это необходимо.   -  person Fogmeister    schedule 05.11.2016
comment
Это не связано с вашим кодом. После обновления до xcode 8.1 даже образцы пустых проектов самого xcode требуют бесконечного развертывания на телефоне, но с симулятором все работает нормально.   -  person alizx    schedule 06.11.2016
comment
@Fogmeister, да, у нас есть несколько init(), которые я удалил для простоты вопроса, поэтому нам нужны эти vars   -  person hoang    schedule 06.11.2016
comment
Удалите все ключи Apple ID из связки ключей, кроме одного. У меня их было 2к!   -  person alizx    schedule 06.11.2016


Ответы (3)


Перепишите без большого словарного литерала. Так:

func toAnyObject() -> Any {
    var d = [String:Any]()
    d["id"] = id
    d["uid"] = uid
    // ... and so on ...
    return d
}
person matt    schedule 05.11.2016

Если вы этого не сделаете, уже добавив флаг компилятора -Xfrontend -debug-time-function-bodies в ваш проект, будет указано время, необходимое для компиляции каждой функции. Это может быть полезным способом определить, что именно тормозит в вашей сборке. (См. http://irace.me/swift-profiling или https://thatthinginswift.com/debug-long-compile-times-swift/).

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

let result: [String: Any] = ["id": id, ...]
return result
person Jonah    schedule 05.11.2016
comment
Я пробовал это, но не работает, Мэттовое решение работает: var d = [String:Any]() d["id"] = id d["uid"] = uid // ... and so on ... return d - person hoang; 06.11.2016

Иногда компилятор тормозит, когда вы выполняете неявную типизацию. Если вы явно добавите информацию о типе, компилятору не нужно будет ее вычислять. Я вижу, что свойства вашего класса в основном содержат информацию о типе, но не все из них. В вашем методе toAnyObject кажется, что вы хотите, чтобы ваш объект был представлен в виде словаря, но вы конвертируете его в тип Any.

Вы делаете словарь буквальным и не предлагаете информации о типе. Явное приведение с помощью "as" может очень помочь.

Когда вы конвертируете что-то в тип Any, Objective-C интерпретирует это как id. Обычно быстрый словарь будет связан с NSDictionary для Objective-c, но вы заставляете его иметь тип Any. По какой причине компилятор должен связать это с NSDictionary? Вероятно, он упаковывает его, так как считает, что это структура, а objective-c не может использовать быстрые структуры.

Постарайтесь не запутать компилятор.

person DerrickHo328    schedule 06.11.2016