我正在调试程序以检查属性值是否正确设置,在此函数中设置了一个断点:
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
}
Run Code Online (Sandbox Code Playgroud)
传递给此函数的值来自视图控制器:
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"))
}
Run Code Online (Sandbox Code Playgroud)
你可以看到,无论是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
}
...
}
Run Code Online (Sandbox Code Playgroud)
这是Swift如何实现该Any类型的详细信息。鉴于Swift无法事先知道您要输入的内容,例如front,它需要存储指向该对象的指针(在中payload_data_0)以及指向有关所存储对象类型的元数据的指针(在中instance_type)。据我所知,payload_data_1并payload_data_2在那里作为优化,使雨燕最多可存储到位24字节的大型结构,而不是把他们在需要被存储在一个单独的堆位置的包装对象。
因此,回答您的问题:这既不是Swift中的错误,也不是您的错误。您的数据将以正确的方式存储和访问。如果您希望front在调试时更轻松地检查,请尝试
(lldb) po front
Run Code Online (Sandbox Code Playgroud)
在调试器中。或者,将front类型更改为例如UIImage?。如果不可能,则可以声明一个协议
protocol MemoryStoreable: class { }
Run Code Online (Sandbox Code Playgroud)
并扩展需要存储在这些字段中的每种类型,如下所示:
extension UIImage: MemoryStoreable { }
Run Code Online (Sandbox Code Playgroud)
并将变量声明为
var front: MemoryStoreable?
Run Code Online (Sandbox Code Playgroud)
请注意,MemoryStoreable它仅限于类,否则将需要存储协议见证者(其实现方式与Any您观察到的字段类似)。
另一个选择是,如果您知道将仅将图像和字符串存储在中front,以使用枚举:
enum MemoryStoreable {
case `string`(String)
case image(UIImage)
}
var front: MemoryStoreable?
Run Code Online (Sandbox Code Playgroud)
不过,这仍然需要在对象中至少存储25个字节(由于内存对齐限制,可能需要32个字节),因为这就是该String结构的大小。
有关更多详细信息,请参见例如https://mikeash.com/pyblog/friday-qa-2014-08-01-exploring-swift-memory-layout-part-ii.html。
| 归档时间: |
|
| 查看次数: |
1871 次 |
| 最近记录: |