2017-02-09 93 views
1

我調試我的程序來檢查屬性的值是否設置正確,我把一個斷點在這個函數:什麼是iOS中的有效載荷數據?

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,而如masteryLevel其他值的數據類型,algorithm是正確的:

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 
} 

... 

} 
+0

對於payload_data,看到https://medium.com/@ vhart/protocols-generics-and-existential-containers-wait-what-e2e698262ab1#.947l6tczk 你的Memory類是什麼樣的? –

+0

@AndreasOetjen謝謝,請參閱更新 –

回答

2

這是斯威夫特如何實現Any型細節。鑑於Swift無法預先知道你正在把什麼放入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字段再次類似d)。

另一種方法是,如果你知道你會存儲例如僅適用於圖像和字符串在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

+0

這是一個非常好的答案,需要一點時間來消化壽,謝謝! –

0

基於@ MrMage的真棒回答。

@MrMage介紹了處理這個問題2組的建議,花了一些 努力爲我掌握他們,我想在 程序來實現的,它是完美的情況下,我去 協議爲本-programming。

這裏是一個非常簡單易懂的教程,幫助我很多: Introduction to Protocol Oriented Programming in Swift

希望這可以幫助你:)