什么是iOS中的有效负载数据?

时间:2017-02-09 06:54:52

标签: ios swift

我正在调试我的程序以检查属性的值是否正确设置,我在这个函数中放了一个断点:

func showContent(data: Any) -> UIView {
    // breakpoint here
    var contentView = UIView()
    if let image = data as? UIImage {
        let imageView = UIImageView()
        imageView.image = image
        contentView = imageView
    }
    if let text = data as? String {
        let label = UILabel()
        label.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        label.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        label.text = text
        contentView = label
    }
    return contentView
}

传递给此函数的值来自视图控制器:

override func viewDidLoad() {
    calcGroupFamiliarity()
    flashCardView.linkedMemory = Memory(masteryLevel: 1, algorithm: Algorithm.algorithm1.chooseAlgorithm(), forgetRatio: 0, lastStudyTime: Date(), front: #imageLiteral(resourceName: "Ideas-Blue"), back: #imageLiteral(resourceName: "Ideas-Yellow"))
}

正如您所看到的,frontback都是图像,但是,在调试器中它们都显示为某些payload_data,而其他值的数据类型如masteryLevelalgorithm是正确的:

enter image description here

有人可以解释一下这意味着什么吗?我该怎么做才能传递正常的图像数据呢?

更新:

这是Memory类:

class Memory: NSObject, NSCoding {

var masteryLevel: Int
var algorithm: [Int: Double]
var forgetRatio: Int
var lastStudyTime: Date
var strength: Double = 0
var front: Any
var back: Any
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask)[0]
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("Memory")

init(masteryLevel: Int, algorithm: [Int: Double], forgetRatio: Int, lastStudyTime: Date, front: Any, back: Any){

    self.masteryLevel = masteryLevel
    self.algorithm = algorithm
    self.forgetRatio = forgetRatio
    self.lastStudyTime = lastStudyTime
    self.front = front
    self.back = back
}

...

}

2 个答案:

答案 0 :(得分:4)

这是Swift如何实现Any类型的详细信息。鉴于斯威夫特事先无法知道你在做什么,例如front,它需要存储指向该对象的指针(在payload_data_0中)以及指向存储对象类型(在instance_type中)的元数据的指针。据我所知,payload_data_1payload_data_2作为优化存在,以便Swift可以存储多达24字节的大型结构,而不必将它们放在需要的包装器对象中存储在单独的堆位置。

所以,回答你的问题:这既不是Swift中的错误,也不是你身边的错误。您的数据以正确的方式存储和访问。如果您希望在调试时更轻松地检查front,请尝试

(lldb) po front
调试器中的

。或者,将front的类型更改为例如UIImage?。如果不可能,您可以声明协议

protocol MemoryStoreable: class { }

并扩展需要存储在这些字段中的每个类型,如下所示:

extension UIImage: MemoryStoreable { }

并将变量声明为

var front: MemoryStoreable?

请注意,MemoryStoreable仅限于类,否则需要存储协议见证(再次实现与您观察到的Any字段类似)。

另一种选择是,如果你知道你会存储,例如只有front中的图片和字符串才能使用枚举:

enum MemoryStoreable {
    case `string`(String)
    case image(UIImage)
}

var front: MemoryStoreable?

但是,对象中仍然需要至少25个字节的存储空间(由于内存对齐限制,可能需要32个字节),因为这是String结构的大小。

有关详细信息,请参阅例如https://mikeash.com/pyblog/friday-qa-2014-08-01-exploring-swift-memory-layout-part-ii.html

答案 1 :(得分:0)

基于@MrMage的精彩答案。

  

@MrMage提出了2个关于解决这个问题的建议,花了一些时间   我努力抓住它们,因为我想要实现的目标   程序,这是我去的完美场景   协议导向编程。

     

这是一个非常容易理解的教程,它对我有很大的帮助:   Introduction to Protocol Oriented Programming in Swift

希望这对您有所帮助:))

相关问题