2015-11-05 2 views
0

У меня есть класс, который действует как BLL, обертывая протокол службы. Протокол службы предоставляет список объектов SerializableObjectProtocol. Например, у меня есть User, который реализует SerializedObjectProtocol.Кастинг генераторного массива в быстрой ошибке приводит к фатальной ошибке

Следующая функция отбрасывает SerializedObjectProtol массива в User

public func Get() -> [T] 
{ 
    let result = self._service.Get() 

    return result as! [T] 
} 

В результате, я получаю следующее сообщение об ошибке:

array element cannot be bridged to Objective-C 

Я знаю, что код подвержены ошибкам, потому что если объект не является T, то кастинг не может произойти. В результате, вот что я могу подтвердить:

  • T в стесненных для реализации SerializedObjectProtol т.е.

    class DataLayer<T:SerializableObjectProtocol> 
    
  • T является типом пользователя. result - это массив пользователей. то есть [User]

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

    var returnArray = [T]() 
    
    for item in result 
    { 
        returnArray.append(item as! T) 
    } 
    
    return returnArray; 
    

Я просто взял Swift для проекта, так что я ограниченный опыт с ним. В результате я пошел посмотреть, возможно ли то, что я пытаюсь (отбрасывание массива [S] до [T]). Кажется, что возможно, если массив равен [Any].

Действительно ли это действительная операция в Swift? Или это невозможно сделать.

ответ

3

Вообще не можно отливать непосредственно между массивом Any к типу он содержит, потому что Any имеет совершенно другое представление в памяти: sizeof(Any) не равен sizeof(User)! Массив из 10 Any s может иметь длину 320 байт, но 10 User s требуется только 80 байт, то же самое относится к любому протоколу. Вывод: вам нужно бросить каждый предмет.

Может быть сделать это следующим образом:

return results.map{ $0 as! User } 

или если вы не уверены, является ли каждый элемент является User, вы можете вернуть только User сек, как это:

return results.flatMap{ $0 as? User } 

Если вы У вас все еще есть проблемы, пожалуйста, напишите какой-то минимальный код, который все еще вызывает ошибку, действительно сложно понять, как выглядит ваш код без фактического кода

+0

Это goo знать. Большое спасибо! Я видел статьи, которые делают [Any] -> [T], но Интернет не всегда является лучшим местом для изучения правильных соглашений. –

+0

Примечание: Смешивание и сопоставление с литьем, как это, как правило, не очень хорошая идея. В этом случае существует абсолютная уверенность в том, что объект является пользователем. Служба настроена так, чтобы возвращать 'SerializableObjectProtocol' для сервисов, которым нужна сериализация (например, WebService, которая может извлекать словарь полей/значений из и в объект).На данный момент, если объект не является пользователем, ошибка произошла где-то в логической цепочке. Кастинг избирательно подобным образом рассматривает коллекцию как сплошные классы и побеждает свободную связь, которая поощряется протоколами. –

+0

@SergueiFedorov Какая цель имеет протокол, когда он может только быть пользователем? Как правило, я думаю, что если вам нужны броски в вашем (чистом) коде Swift, вы делаете что-то не так, я не использовал их вообще при программировании с помощью чистого Swift (нет ObjC, нет JSON и т. Д.) – Kametrixom

Смежные вопросы