После обновления 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
как это исправить?
Когда это происходит, процесс с именем SourceKitService использует более 13 ГБ памяти на моем компьютере размером 8 ГБ. Обычно используется чуть больше 300 МБ. Оказывается, некоторые выражения создают утечки памяти в процессе сборки.
Должен признаться, я закатил глаза, когда увидел эту ошибку
Вот еще один нелепый пример: возврат
Освободите память и ошибка исчезнет! :)





Просто попробуйте разбить выражение на несколько более простых подвыражений. Например.:
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
Я видел это раньше и не понимал почему, и в итоге сделал код проще. Этот ответ прояснил ситуацию. Спасибо.
Работал! Я ненавижу XCode с каждым днем все больше и больше ... плохая IDE!
@Pelanes Я здесь не для того, чтобы защищать XCode, но это вызвано не IDE, а компилятором ...
Я также вижу эту ошибку компилятора, и как разработчик более 30 лет это просто смешно. Итак, в 2019 году наша задача как разработчика ... не заставлять компилятор работать слишком тяжело? Компиляторы анализировали выражения намного, намного, намного сложнее, чем это, на протяжении более полувека. Это принудительное применение стиля кодирования из-за ошибки компилятора, что неверно.
Я опытный разработчик C# и Java и перехожу к разработке на Swift ... и я только что столкнулся с этой проблемой. Шутки в сторону? Я просто использую print («мои значения: + self.something1 +», «+ ... +», «+ self.something6»). И это для компилятора многовато? Я выплюнул список из 100 переменных в C#, а компилятор даже не моргнул. Это языковая шутка.
Итак, у меня есть такое выражение:
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
Спасибо. Это действительно маскировало основную ошибку. В моем случае пытаюсь выполнить итерацию по собственному протоколу.
Это действительно проблема с памятью. Это случилось со мной, когда у меня на 16-гигабайтной машине было всего 350 Мб свободной памяти. Использование f.e. CleanMyMac -> Освободить память решила эту проблему.
Не проблема с памятью. Ошибка воспроизводится на машинах с 24 ГБ свободной памяти.
Вы уверены, что процесс xCode может выделить больше памяти, даже если она доступна? Обычно существуют ограничения на размер кучи и стек для каждого процесса.
Освободить память у меня сработало. Свободная память составляла 1,2 из 32 ГБ при появлении ошибки после успешной сборки 13,29 из 32 ГБ
Я регулярно вижу эту проблему при работе со SwiftUI, и она всегда была результатом синтаксической ошибки. В настоящее время я использую Xcode 11.4.1, и это было верно для более ранних версий, поддерживающих SwiftUI.
Например, я просто прожег 50 минут с этой ошибкой, потому что я изменил имя параметра функции в другом файле. Компилятор сообщил об этой ошибке в файле SwiftUI, который был полностью нетронутым, за исключением того, что он вызвал функцию без измененного имени параметра. Вместо того, чтобы явно указывать на несоответствие имени параметра, возникает эта ошибка.
Эта ошибка возникает, когда компилятор запутался. Я столкнулся с этим, выполняя длительные вычисления, которые смешивают различные типы чисел
Я смог исправить это, добавив различные подсчеты в CGFloat. Мне не нужно было «разбивать» выражения, как подсказывают некоторые ответы.
Просто сделав это:
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)
}
}
Являются ли какие-либо значения в этом коде вычисленными значениями? например
options.textWidth? Вы можете попробовать указать класс для каждой переменной, а не полагаться на вывод типа. напримерlet spaceFromLeftSide: CGFloat =