我正在调试我的程序以检查属性的值是否正确设置,我在这个函数中放了一个断点:
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"))
}
正如您所看到的,front
和back
都是图像,但是,在调试器中它们都显示为某些payload_data
,而其他值的数据类型如masteryLevel
,algorithm
是正确的:
有人可以解释一下这意味着什么吗?我该怎么做才能传递正常的图像数据呢?
更新:
这是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
}
...
}
答案 0 :(得分:4)
这是Swift如何实现Any
类型的详细信息。鉴于斯威夫特事先无法知道你在做什么,例如front
,它需要存储指向该对象的指针(在payload_data_0
中)以及指向存储对象类型(在instance_type
中)的元数据的指针。据我所知,payload_data_1
和payload_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
希望这对您有所帮助:))