Проблема с обобщениями Swift 2.2 (Xcode 7.3)

У меня разочаровывающая ситуация со Swift 2.2 (Xcode 7.3). Чтобы смоделировать это, просто создайте переменную в определяемом пользователем универсальном классе и ссылайтесь на этот класс из другого места. Например:

class A<T> {
    let genVar = 1
}

class MyViewController: UIViewController {
    let myVar = A<Int>() // crash is here
}

Если вы запустите этот код на устройстве под управлением iOS 7 (в моем случае iPhone 4), он потерпит крах при попытке создать переменную универсального типа. Вот первые строки журнала сбоя устройства:

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: KERN_PROTECTION_FAILURE at 0x00298910
Triggered by Thread:  0

Thread 0 Crashed:
0   libswiftCore.dylib              0x006b1d64 0x4bd000 + 2051428
1   Phone                           0x001c76ec 0xab000 + 1165036
2   libswiftCore.dylib              0x006b307c 0x4bd000 + 2056316
3   libswiftCore.dylib              0x006b2f70 0x4bd000 + 2056048
4   libswiftCore.dylib              0x006b0f24 0x4bd000 + 2047780
5   libswiftCore.dylib              0x006b107c 0x4bd000 + 2048124
6   Phone                           0x0014e730 0xab000 + 669488
7   Phone                           0x00129390 0xab000 + 517008
8   UIKit                           0x31e9d9c4 -[UIClassSwapper initWithCoder:] + 188

На симуляторах /устройствах iOS 8 и 9 приведенный выше код работает нормально.

Будет ли прекращена поддержка Swift для iOS 7 в ближайшем будущем?

7 голосов | спросил Vas 26 MarpmSat, 26 Mar 2016 15:37:05 +03002016-03-26T15:37:05+03:0003 2016, 15:37:05

4 ответа


0

Я был ошарашен двумя ошибками с использованием дженериков Swift в iOS 7. Вот как их исправить.

Ошибка № 1 - вы должны определить универсальное в качестве первого свойства в вашем классе, прежде чем другие.

Пример - этот код не выполняется:

public class TestIOS7<T> {

    private var x: Int?
}

let x = TestIOS7<String>()

Но вот обходной путь:

public class TestIOS7<T> {

    private var kludge: T?
    private var x: Int?
}

let x = TestIOS7<String>()

Ошибка № 2: ограничения класса кажутся полностью нарушенными.

Пример - этот код не выполняется:

class ClassA<B: ClassB> { }

class ClassB { }

let x = ClassA <String>()

Я не нашел никакого обходного пути, кроме удаления ограничения "ClassB" и переписывания всего кода, чтобы учесть тот факт, что в основном эта языковая функция больше не существует. Это особенно болезненно, когда вам нужно вызвать инициализатор ClassB из ClassA - мне пришлось переписать этот блок с помощью аппаратного if /then /else для всех моих подклассов ClassB, пока Apple не исправит это.

Если кто-то найдет обходной путь для ошибки №2, сообщите мне об этом!

ответил alpsystems.com 2 AMpSat, 02 Apr 2016 01:24:24 +030024Saturday 2016, 01:24:24
0

Как показывает эта ошибка , у вас есть следующие возможные обходные пути:

  • сделать класс неуниверсальным
  • удалить value свойство
  • Свойства
  • swap object и value декларации
  • инициализировать объект в init

Вероятно, лучший обходной путь - это инициализация объекта в init:

class A<T> {
    let genVar: Int
    init() {
       genVar = 1
    }

}

class MyViewController: UIViewController {
    let myVar = A<Int>() // no crash
}
ответил Daniel 30 MarpmWed, 30 Mar 2016 12:16:41 +03002016-03-30T12:16:41+03:0012 2016, 12:16:41
0

Мы столкнулись с той же проблемой.

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

Я также разместил этот ответ в ошибке , посвященной SimpleBob .

Пример:

// This heavily pollutes the codebase, so let's keep track of it but using a common meaningless generic value so we can find and destroy later when we no longer support iOS7
protocol iOS7SwiftGenericFixProtocol {}
struct iOS7SwiftGenericFixType: iOS7SwiftGenericFixProtocol {}

class GenericClass<T> {
    var value: T?
    let attribute = 0
}

class GenericSubclass<Element: iOS7SwiftGenericFixProtocol>: GenericClass<Int> {
    let otherAttribute = 0
}

let _ = GenericSubclass<iOS7SwiftGenericFixType>()
ответил ryanholden8 26 J000000Tuesday16 2016, 22:16:54
0

В Xcode 7.3.1 единственная проблема с моим родовым классом заключалась в том, что он наследовал от NSObject. Удаление наследства было достаточно, порядок декларирования собственности не имел значения.

ответил Nickkk 9 J000000Sunday17 2017, 14:50:34

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132