Строковый код работает в lldb `p`, код не проходит в размещенном модульном тесте

Я нашел множество постов о NSArray element failed to match the Swift Array Element type ошибка. Тем не менее, я до сих пор не могу заставить это работать. Я подозреваю, что проблема связана с выполнением привязки целевого фреймворка C и не является проблемой приведения. Среди прочего, я не понимаю, почему код работает внутри lldb p инструкция, но не в виде модульного теста, выполняемого в приложении хоста ios (иначе я не могу проверить его, поскольку для кода требуется B-LE, который недоступен в симуляторе iphone).

class onceFirstMuseConnected: IXNMuseListener {
    let museManager: IXNMuseManager
    let callback: (_ muse: IXNMuse) -> Void

    init(museManager: IXNMuseManager, callback: @escaping (_ muse: IXNMuse) -> Void) {
        self.museManager = museManager
        self.callback = callback
        museManager.setMuseListener(self)
        museManager.startListening()
    }

    func museListChanged() {
        let muses: [IXNMuse] = museManager.getMuses()
        guard muses.count > 0 else {
            return
        }
        let _ = muses.first!.getName() // <<<< `muses.first` fails as well as any other
                                       //      kind of array's item access with "Fatal
                                       //      error: NSArray element failed to match the
                                       //      Swift Array Element type"
    }
}

Что странно, так это то, что я могу заставить линию работать в lldb, как показано на рисунке ниже.

ллдб работает

edit: так как у меня есть несколько downvote, я был бы признателен за объяснение того, почему строка lldb работает в комментариях, в то время как основное выполнение падает. Я предполагаю, что строка lldb не будет работать, если это будет проблема преобразования типов. Ни один из связанных вопросов, которые я нашел, не отвечает на этот вопрос. Я признаю, что я новичок в swift / objc, вероятно, есть что-то очевидное, чего я не понимаю, если это не проблема, связанная с процессом отображения структуры objc-swift.

getMuses Функция обернута Джинни, используя карту модулей, которую я написал, чтобы связать проприетарную целевую инфраструктуру C с swift. Вот карта модуля, которую я написал. У меня еще не было проблем с другими привязками функций (см. Комментарии). Удаление [system] атрибут не вызывает никакого дополнительного предупреждения.

module Muse [system] {
    header "Muse.framework/Headers/Muse.h"
    export *
}

Джинни сгенерировал объявление:

public func getMuses() -> [IXNMuse]

Оригинальная декларация objc:

 - (nonnull NSArray<IXNMuse *> *)getMuses;

Определение недоступно, поскольку структура является собственностью.

Возвращенный указатель вряд ли будет нулевым или будет указывать на неправильный адрес памяти, так как вызов lldb для метода getName, показанного на снимке экрана, не даст должного результата, если это так.

1 ответ

Решение

Отредактированный ответ

Muse.framework - это статическая структура. XCTests встроены в пакет, встроенный в хост-приложение. В моей настройке участвуют 3 цели: разрабатываемая мной среда, хост-приложение для тестирования и пакет XCTest.

Статическая структура встраивает символы , которые используются внутри целевых двоичных файлов.

Чтобы избежать повторяющихся проблем с символами, статические платформы должны быть связаны только с целевой платформой **, а не с пакетом xctest или тестовым хост-приложением, которые временно связывают символы, связывая целевую платформу.

Чтобы убедиться, что целевая платформа встраивает все символы своей статически связанной зависимости платформы, необходимо добавить флаг -force_load, за которым следует путь статической зависимости, к параметрам связывания целевой платформы (OTHER_LDFLAGS).

Оригинальный ответ

OOPer к OOPer за помощью в комментарии к вопросу.

По причине, которую я не понимаю, я получил двойное определение моего класса IXNMuse. Свифт, противоречащий между этими двумя определениями, стал причиной NSArray element failed to match the Swift Array Element type ошибка у меня была.

Исправить процедуру

Проблема исчезла, когда я сделал следующую процедуру:

A. Во время тестирования следующего кода

let muses: NSArray = museManager.getMuses() as NSArray
let muse: IXNMuse = muses.firstObject! as! IXNMuse

Я получил во время выполнения

Could not cast value of type 'IXNMuse' (0x103cfa180) to 'IXNMuse' (0x103e965e0).

Б. У меня было два import Muse оператор, один в моем тестовом файле, один в одном из моего целевого исходного файла фреймворка. Удаление import Muse выписка из тестового файла (с соответствующим кодом). Это позволило пройти тест, удалив двойное определение IXNMuse.

C. Я удалил Muse.framework от Link Binary with Libraries моей тестовой цели, поскольку она уже была включена в мою протестированную базовую цель. Я положил обратно import Muse Выписка из тестового файла (со связанным кодом, как мне все еще было нужно), которую я только что удалила. Тест по-прежнему проходил даже при двойном импорте Muse в исходные файлы обеих целей.

D. Я положил обратно Muse.framework назад к Link Binary with Libraries моей тестовой цели (я считаю, что это не ошибка, что обе цели связывают одну и ту же структуру с треугольной зависимостью). Таким образом, я вернулся к состоянию, аналогичному тому, в котором я находился при написании вопроса. Проблема не появилась снова, и тестирование все еще проходит.

Заключение

Я все еще немного смущен, почему у меня была проблема сначала. Возможно, я был не совсем в том же состоянии, хотя я и что-то делал в процессе изменения конфигурации ссылок, я не помню.

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