Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is payload data in iOS?

Tags:

ios

swift

I'm debugging my program to check if the value of a property is correctly set. I put a breakpoint in this function:

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
}

The value passed to this function is from a view controller:

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"))
}

As you can see, both the front and the back are images, however, in the debugger, they both appeared as some payload_data, while the data type of other values such as masteryLevel and algorithm are correct:

enter image description here

Can somebody explain what that means? And what should I do to pass the normal image data instead?

Update:

This is Memory class:

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
}

...

}
like image 715
Bright Avatar asked Feb 09 '17 06:02

Bright


1 Answers

This is a detail of how Swift implements the Any type. Given that Swift can't know beforehand what you are putting into e.g. front, it needs to store a pointer to that object (in payload_data_0) as well as a pointer to metadata about the stored object's type (in instance_type). As far as I know, payload_data_1 and payload_data_2 are there as an optimization so that Swift can store up to 24-byte large structs in place rather than having to put them in a wrapper object that needs to be stored in a separate heap location.

So, to answer your question: This is neither a bug in Swift, nor an error on your side. Your data gets stored and accessed in the right way. If you would prefer to inspect front more easily while debugging, try

(lldb) po front

in the debugger. Alternatively, change front's type to e.g. UIImage?. If that is not possible, you could declare a protocol

protocol MemoryStoreable: class { }

and extend every type that needs to be stored in those fields like so:

extension UIImage: MemoryStoreable { }

and declare the variable as

var front: MemoryStoreable?

Note that MemoryStoreable is restricted to classes, as otherwise a protocol witness would need to be stored (which is again implemented similarly to the Any field you observed).

Another alternative would be, if you know you'll store e.g. only images and strings in front, to use an enum:

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

var front: MemoryStoreable?

That will still require at least 25 bytes of storage in your object (possibly 32 due to memory alignment constraints), though, as that's the size of the String struct.

For more details, see e.g. https://mikeash.com/pyblog/friday-qa-2014-08-01-exploring-swift-memory-layout-part-ii.html.

like image 171
MrMage Avatar answered Oct 27 '22 06:10

MrMage