Конструкторы в Swift? - PullRequest
0 голосов
/ 09 ноября 2018

В Java мы можем использовать конструкторы для передачи начальных значений в класс.Возможно ли это в кратчайшие сроки?

Например, в строке ниже я пытаюсь добавить объект, который должен включать все значения, которые вы можете видеть в функции, которая находится внутри него, в массив с именем arrayOfMedia.

self.arrayOfMedia.append(Media().getUsersMedia(image: image!, postNum: anyPosts.key, userID: user))

Однако я не могу этого сделать и получаю ошибку ниже.

Невозможно преобразовать значение типа '()' в ожидаемый тип аргумента 'Media'

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Для чего бы это ни стоило, в этом случае я бы использовал enums для переноса типов ваших медиа.

enum MediaType {
    case image(UIImage)
    case video(Data) 
}

Тогда у вас есть тип безопасного доступа без дополнительных опций:

struct Media {
    let postKey: Int
    let userId: Int
    let mediaType: MediaType
}

let video = Media(postKey: 1, userId: 2, mediaType: .video(dataVariable))
let image = Media(postKey: 2, userId: 3, mediaType: .image(imageVariable))
0 голосов
/ 09 ноября 2018

Я не хочу инициализировать класс, так как входящие в него значения различаются (иногда видео, а иногда и изображение)

Хорошо, это не имеет смысла, у вас есть class, который является контейнером для некоторых данных, некоторые из которых являются необязательными (либо у вас есть изображение или видео), почему бы не предоставить два разных инициализатора для двух разные варианты использования ... как в Java?

Есть несколько способов, которыми вы могли бы достичь этого, только один ...

class Media {
    var image: UIImage?
    var video: Data?
    let postKey: Int
    let userId: Int

    internal required init(postKey: Int, userId: Int) {
        self.postKey = postKey
        self.userId = userId
    }

    convenience init(image: UIImage, postKey: Int, userId: Int) {
        self.init(postKey: postKey, userId: userId)
        self.image = image
    }

    convenience init(video: Data, postKey: Int, userId: Int) {
        self.init(postKey: postKey, userId: userId)
        self.video = video
    }
}

Кроме того, обратите внимание, вы могли бы просто предоставить один инициализатор, что-то вроде ...

init(image: UIImage? = nil, video: Data? = nil, postKey: Int, userId: Int) {...}

, но это не ограничивает пользователя тем или иным типом (они все равно могут передавать nil для обоих значений)

Другой подход может состоять в том, чтобы использовать protocol для описания основных / общих свойств Media и затем реализовывать различные требования (прямо как struct s или class s или косвенно как дополнительные protocols)

Например ...

protocol Media  {
    var postKey: Int { get }
    var userId: Int { get }
}

struct VideoMedia: Media {
    let postKey: Int
    let userId: Int
    let video: Data
}

struct ImageMedia: Media {
    let postKey: Int
    let userId: Int
    let image: UIImage
}
...