Компилятор не может проверить тип этого выражения swift 4?

После обновления xCode я получаю эту ошибку в своем коде:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Код :

//check popup in window frame

let spaceFromLeftSide = cutOutViewX.constant + cutOutViewWidth.constant/2 - (options.textWidth + padding*2)/2

if spaceFromLeftSide < 0{

    if options.side == .bottom {
        messageRightSpaceFromBottomDot.constant -= spaceFromLeftSide - padding
    }
    else if options.side == .top{
        messageRightSpaceFromTopDot.constant += spaceFromLeftSide - padding
    }
}

let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2

if spaceFromRightSide > targetView.frame.size.width{

    if options.side == .bottom {
        messageRightSpaceFromBottomDot.constant -= spaceFromRightSide - ( targetView.frame.size.width )
    }
    else if options.side == .top{
        messageRightSpaceFromTopDot.constant += spaceFromRightSide - ( targetView.frame.size.width )
    }
}

Ошибка в строке:

let spaceFromRightSide = cutOutViewX.constant + cutOutViewWidth.constant/2 + (options.textWidth + padding*2)/2

как это исправить?

Являются ли какие-либо значения в этом коде вычисленными значениями? например options.textWidth? Вы можете попробовать указать класс для каждой переменной, а не полагаться на вывод типа. например let spaceFromLeftSide: CGFloat =

Ashley Mills 18.09.2018 11:00

Когда это происходит, процесс с именем SourceKitService использует более 13 ГБ памяти на моем компьютере размером 8 ГБ. Обычно используется чуть больше 300 МБ. Оказывается, некоторые выражения создают утечки памяти в процессе сборки.

Gerd Castan 31.12.2018 14:23

Должен признаться, я закатил глаза, когда увидел эту ошибку

Brad Thomas 11.03.2019 05:02

Вот еще один нелепый пример: возврат

user33775 08.04.2019 05:10

Освободите память и ошибка исчезнет! :)

Gope 08.08.2019 08:46
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
84
5
65 629
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Просто попробуйте разбить выражение на несколько более простых подвыражений. Например.:

let halfOfViewWidth = cutOutViewWidth.constant / 2
let textWidthAndPadding = options.textWidth + (padding * 2)
let spaceFromRightSide = cutOutViewX.constant + halfOfViewWidth + (textWidthAndPadding / 2)

РЕДАКТИРОВАТЬ

Я заметил, что мне удалось исправить этот тип ошибки также путем явного преобразования типов (например, вместо того, чтобы полагаться на компилятор, чтобы сделать вывод, что, умножая CGFloat на Int, это должно привести к CGFloat, я явно преобразовал Int в CGFloat). Похоже, что проблема действительно в типах и автоматическом выводе и проверке типов. Хотя разбиение сложного выражения на более мелкие части может быть очень полезно для удобочитаемости, вы можете решить проблему, явно указав типы (сообщение об ошибке в основном говорит о том, что компилятор не может выполнить проверку типа - таким образом, вы можете помочь ему, предоставление явных типов везде, где это возможно).

Ответ принят как подходящий

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

Эта ошибка появляется, когда компилятор Swift обнаруживает, что вычисление выражения занимает много времени. Подробнее проверьте здесь

Чтобы решить эту проблему, вам просто нужно разбить выражение на более мелкие части. Как:

let cutOutxOrigin = 3 * cutOutViewX.constant / 2
let actualPadding = (options.textWidth + padding * 2) / 2

let spaceFromRightSide = cutOutxOrigin + actualPadding

Я видел это раньше и не понимал почему, и в итоге сделал код проще. Этот ответ прояснил ситуацию. Спасибо.

beshio 18.09.2018 11:29

Работал! Я ненавижу XCode с каждым днем ​​все больше и больше ... плохая IDE!

Pelanes 17.01.2019 10:19

@Pelanes Я здесь не для того, чтобы защищать XCode, но это вызвано не IDE, а компилятором ...

Greg Hilston 30.01.2019 17:37

Я также вижу эту ошибку компилятора, и как разработчик более 30 лет это просто смешно. Итак, в 2019 году наша задача как разработчика ... не заставлять компилятор работать слишком тяжело? Компиляторы анализировали выражения намного, намного, намного сложнее, чем это, на протяжении более полувека. Это принудительное применение стиля кодирования из-за ошибки компилятора, что неверно.

Dan 17.02.2019 13:35

Я опытный разработчик C# и Java и перехожу к разработке на Swift ... и я только что столкнулся с этой проблемой. Шутки в сторону? Я просто использую print («мои значения: + self.something1 +», «+ ... +», «+ self.something6»). И это для компилятора многовато? Я выплюнул список из 100 переменных в C#, а компилятор даже не моргнул. Это языковая шутка.

jo phul 25.04.2019 05:02

Итак, у меня есть такое выражение:

return (50 + textHeight) + (dateTextHeight + 16) + (5 + 8) + (16 + 20)

Я знал, что мне нужно разбить или сделать это выражение короче, чтобы избавиться от ошибки. Возможно, вроде:

return (50 + textHeight) + (dateTextHeight + 16) + 49

Хотя это правда, что это помогло компилятору выполнять свою работу, основной причиной ошибки является необязательный Int textHeight. Я думаю, независимо от того, как долго ваше выражение, оно должно быть компилируемым.

Я столкнулся с аналогичной проблемой с другим сценарием

Я пытался создать массив строк

let selectedData = [
        (data?.nose?.stuffyNose) ?? "",
        (data?.nose?.sinusProblems) ?? "",
        (data?.nose?.hayFever) ?? "",
        (data?.nose?.sneezingAttacks) ?? "",
        (data?.nose?.excessiveMucusFormation) ?? ""
] 

Я уже добавил скобки (), но все еще не работал.


Чтобы исправить это, я добавил тип [String]

let selectedData:[String] = [
        (data?.nose?.stuffyNose) ?? "",
        (data?.nose?.sinusProblems) ?? "",
        (data?.nose?.hayFever) ?? "",
        (data?.nose?.sneezingAttacks) ?? "",
        (data?.nose?.excessiveMucusFormation) ?? ""
] 

Надеюсь, это поможет кому-то, кто сталкивается с той же проблемой

У меня была эта ошибка, когда я случайно добавил необязательный параметр в выражение. После принудительного развертывания ошибка исчезла.

let a : String = "A" 
let b : String = "B" 
let c = letterDictionary["C"]

let imageName : String = a + b + c //error 
let imageName : String = a + b + c! //no error 

Спасибо. Это действительно маскировало основную ошибку. В моем случае пытаюсь выполнить итерацию по собственному протоколу.

Dirk Bester 22.05.2020 00:46

Это действительно проблема с памятью. Это случилось со мной, когда у меня на 16-гигабайтной машине было всего 350 Мб свободной памяти. Использование f.e. CleanMyMac -> Освободить память решила эту проблему.

Не проблема с памятью. Ошибка воспроизводится на машинах с 24 ГБ свободной памяти.

Ckacmaster 28.09.2019 05:03

Вы уверены, что процесс xCode может выделить больше памяти, даже если она доступна? Обычно существуют ограничения на размер кучи и стек для каждого процесса.

Gope 07.10.2019 09:19

Освободить память у меня сработало. Свободная память составляла 1,2 из 32 ГБ при появлении ошибки после успешной сборки 13,29 из 32 ГБ

ilker 04.11.2020 18:44

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

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

Эта ошибка возникает, когда компилятор запутался. Я столкнулся с этим, выполняя длительные вычисления, которые смешивают различные типы чисел

Я смог исправить это, добавив различные подсчеты в CGFloat. Мне не нужно было «разбивать» выражения, как подсказывают некоторые ответы.

  • От: (некоторое выражение с плавающей запятой) * someDouble / someInt
  • Кому: (некоторое выражение с плавающей запятой) * CGFloat (someDouble / someInt)

Просто сделав это:

    let array = [Int]()
    let dic   = [Int : Double]()
    
    let tuple = array.map { c -> (a: Int, b: Double) in return (a: c, b: dic[c]!) }.sorted(by: { (first, second) -> Bool in return first.b == second.b ? first.a < second.a : first.b > second.b }).first!

Xcode 11.6 занимает 10 секунд ЦП с 4 процессами, работающими на 100%, потребляя много Вт на моем MacPro 2019, и я получил ошибку: (Компилятор не может проверить это выражение за разумное время; попробуйте разбить выражение на отдельные подвыражения)

Даже если объединить только карту и сорт!

Если я разделю на 2:

let temporaryTupleArrayToAvoidTheCompilerBug = array.map { c -> (a: Int, b: Double) in return (a: c, b: dic[c]!) }

let tuple = temporaryTupleArrayToAvoidTheCompilerBug.sorted(by: { (first, second) -> Bool in return first.b == second.b ? first.a < second.a : first.b > second.b }).first!

Оно работает.

Сообщение об ошибке здесь, чтобы скрыть ошибку, компилятор может разделить инструкцию и отдельно проверить синтаксис методов.

Один случай возможный заключается в том, что я соединяю строку с enum.

например:

enum Fruit: String {
    case apple
}

let fruit = Fruit.apple

тогда я сращиваю возникает ошибка

let url = "/api/" + fruit

Fruit - это поле Enum, а не String. Я исправляюсь с помощью

let url = "/api/" + fruit.rawValue

Это случилось со мной. Я передавал два Float в структуру SwiftUI и вычитал один из другого внутри, но по ошибке я определил Float внутри как Dates (черт возьми, копипаст!).

В основном это было так.

struct Something: View {
    var minValue: Date
    var maxValue: Date

    var body: some View {
        let valueDifference = maxValue - minValue
    }
}

Я называл это так:

let minValue: Float = 0
let maxValue: Float = 1

Something(minValue: minValue, maxValue: maxValue)

Обратите внимание, что на самом деле я передаю два Float, но структура принимает их, даже если они определены как Date.

Как только я сменил типы Date на Float, проблема исчезла.

У меня было выражение с несколькими вариантами использования необязательной переменной с запасными значениями, например:

if ((self.scrollView?.contentSize.width ?? 0.0) > 0.0) && ((self.scrollView?.contentSize.height ?? 0.0) > 0.0) && ((self.scrollView?.frame.size.height ?? 0.0) > 0.0) {

Ошибка исчезла, когда я сделал необязательную копию переменной:

guard let scrollView = self.scrollView else { return }
if (scrollView.contentSize.width > 0.0) && (scrollView.contentSize.height > 0.0) && (scrollView.frame.size.height > 0.0) {

В зависимости от того, что вы хотите сделать, когда необязательная переменная равна nil, эта однострочная версия также может быть полезна:

if let scrollView = self.scrollView, (scrollView.contentSize.width > 0.0), (scrollView.contentSize.height > 0.0), (scrollView.frame.size.height > 0.0) {

У меня была такая же проблема:

@State var sliderpos : CGFloat = (UIScreen.main.bounds.width-32)*(50/100)+(16-20) //causes error

Но это, с другой стороны, работает:

@State var sliderpos : CGFloat = (UIScreen.main.bounds.width-32)*(50/100)-4

Я столкнулся с этой проблемой на Firebase при обновлении данных для отдельных ключей в соответствии с документацией.

// Update Cards
        self.database.collection(FirebaseDatabaseKeys.cards).document(docId).setData([
            "id": docId,
            "cardNumber": card.cardNumber ?? "",
            "isFavorite": card.isFavorite,
            "numberOfCards": card.numberOfCards,
            "playerName": card.playerName?.uppercased() ?? "",
            "year": card.year ?? "",
            "sport": card.sport ?? "",
            "brand": card.brand ?? "",
            "set": card.set ?? "",
            "parallel": card.parallel ?? "",
            "serial": card.serial ?? "",
            "owner": uid ?? "",
            CardSide.frontCard.imageKey: "",
            CardSide.backCard.imageKey: ""
        ]) { err in
            if let error = err {
                print(error.localizedDescription)
            }
        }

Я разрешаю создать словарь до вызова setData

    // Create Data
    let cardData: [String: Any] = [
        "id": docId,
        "cardNumber": card.cardNumber ?? "",
        "isFavorite": card.isFavorite,
        "numberOfCards": card.numberOfCards,
        "playerName": card.playerName?.uppercased() ?? "",
        "year": card.year ?? "",
        "sport": card.sport ?? "",
        "brand": card.brand ?? "",
        "set": card.set ?? "",
        "parallel": card.parallel ?? "",
        "serial": card.serial ?? "",
        "owner": uid ?? "",
        CardSide.frontCard.imageKey: "",
        CardSide.backCard.imageKey: ""
    ]

    // Update Cards
    self.database.collection(FirebaseDatabaseKeys.cards).document(docId).setData(cardData) { err in
        if let error = err {
            print(error.localizedDescription)
        }
    }

Другие вопросы по теме