Контрольные точки свойств класса Swift исчезают после метода init - PullRequest
0 голосов
/ 16 мая 2018

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

Мне было поручено написать приложение VoIP для IOS с использованием библиотеки PJSIP.

Моя функция макета работала нормально, и я начал сортировать вещи по их собственным классам, где все начало разваливаться.

Библиотека C требует большого количества переменных / указателей, на которые ссылаются. С моим новым экземпляром класса, если я помещаю все в конструктор init (), это работает. Но когда я начинаю разделять некоторые части для разделения методов внутри одного и того же класса, переменные, кажется, меняют контрольные точки.

Вот макет, написанный в блокноте, так как я не могу предоставить сам код, и в этот час у меня нет доступа к Mac:

class Account {
    var accId: c_library_type = 0
    var accCfg: c_library_type2 = c_library_type2()

    init()
    {
        c_config_setting_defaults(&self.accCfg)
        //other code
    }

    public func register()
    {
        c_register_method(&self.accId, &self.accCfg) //Throws "exc_bad_access code=1 address=0x0"
    }   
}

//Somewhere else in the code

var account: Account = Account()
account.register()  

Если бы я должен был сделать

class Account {
    var accId: c_library_type = 0
    var accCfg: c_library_type2 = c_library_type2()

    init()
    {
        c_config_setting_defaults(&self.accCfg)
        //other code
        c_register_method(&self.accId, &self.accCfg)
    }   
}

//Somewhere else in the code

var account: Account = Account()

Нет проблем, и c_register_method работает как положено.

Буду очень признателен за любую помощь по этому вопросу.

Edit: библиотека c файлом и методами, которые выдают исключение памяти: https://github.com/chakrit/pjsip/blob/master/pjsip/src/pjsua-lib/pjsua_acc.c#L116 https://github.com/chakrit/pjsip/blob/master/pjsip/src/pjsip/sip_util.c#L435

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

С некоторой помощью наших разработчиков на C мы нашли причину этой проблемы.

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

Пример:

variable1 :: refId = 0x001
variable1.prop1 :: refId = 0x0011
variable1.prop2 :: refId = 0x0012
variable1.prop3 :: refId = 0x0013

Reference passed to the C library:

(copy) variable1 :: refId = 0x002
variable1.prop1 :: refId = 0x0011
variable1.prop2 :: refId = 0x0012
variable1.prop3 :: refId = 0x0013

Библиотека проверила, отличалась ли контрольная точка массива от первой контрольной точки значения. Если это так, то предполагается, что массив не пустой.

Поскольку основная ссылка была скопирована, следовательно, имела другую контрольную точку, в коде предполагалось, что существует некоторое значение, которого на самом деле не существует, и мы получили bad_access из-за попытки получить доступ к несуществующей ссылке.

Проблема была решена путем изменения метода register () для получения параметров как inout вместо использования self.

Пример на основе предыдущего макета:

class Account {
    var accId: c_library_type = 0
    var accCfg: c_library_type2 = c_library_type2()

    init()
    {
        c_config_setting_defaults(&self.accCfg)
        //other code
    }

    public func register(id: inout c_library_type, cfg: inout c_library_type2)
    {
        c_register_method(&id, &cfg)
    }   
}

//Somewhere else in the code

var account: Account = Account()
account.register(id: &account.accId, cfg: &account.accCfg)  

Спасибо, что уделили время любому, кто прокомментировал проблему.

0 голосов
/ 16 мая 2018

Я не вижу причины использования оператора &, так как ссылочные типы по умолчанию передаются по ссылке, а оператор & нужен только тогда, когда вам нужно работать с типами значений, чтобы передать их адрес памяти в качестве ссылки, которую нужно изменить. Я думаю, это должно решить проблему, если функция не принимает значения типов в C.

...