-
Notifications
You must be signed in to change notification settings - Fork 96
Open
Description
Runtime is not able to calculate the correct ivar offsets under some specific circumstances. Take a look at the following example:
import Foundation
import Runtime
class IncorrectLayout: NSObject {
let ivar1 = AttributedString("ivar1") // Value type
let ivar2 = NSDate() // Reference type
}Inspecting this type through Runtime gives the following offsets:
PropertyInfo(name: "ivar1", type: Foundation.AttributedString, isVar: false, offset: 0, ownerType: ...)
PropertyInfo(name: "ivar2", type: NSDate, isVar: false, offset: 8, ownerType: ...)
But that's not correct as far as I understand. According to ivar_getOffset the offsets are off by 8 bytes. Because of that, using get(from:) will return an instance pointing to an invalid memory address, resulting in a crash when invoking any method on it. Eg:
let instance = IncorrectLayout()
let info = try typeInfo(of: IncorrectLayout.self)
try info.properties.forEach { property in
if property.name == "ivar2" {
let ivar = try property.get(from: instance) as NSDate
print(ivar.timeIntervalSinceNow) // Unrecognized selector -[_TtCV10Foundation16AttributedString4Guts timeIntervalSinceNow]!
}
}Additional notes
Attempting to change almost anything from IncorrectLayout will likely fix the issue. Eg:
- Removing the
NSObjectsuperclass - Changing the type of ivar1 to a reference type
- Removing ivar1
Metadata
Metadata
Assignees
Labels
No labels