Edw*_*eer 19 reflection setvalue swift
在Swift中,它不可能使用 .setValue(..., forKey: ...)
Int?enum类型的属性[MyObject?] 这有一个解决方法,即通过覆盖对象本身中的setValue forUndefinedKey方法.
因为我正在编写一个基于反射的通用对象映射器.请参阅EVReflection我希望尽可能地减少这种手动映射.
还有其他方法可以自动设置这些属性吗?
解决方法:可以在我的库中的单元测试发现这里 这是代码:
class WorkaroundsTests: XCTestCase {
func testWorkarounds() {
let json:String = "{\"nullableType\": 1,\"status\": 0, \"list\": [ {\"nullableType\": 2}, {\"nullableType\": 3}] }"
let status = Testobject(json: json)
XCTAssertTrue(status.nullableType == 1, "the nullableType should be 1")
XCTAssertTrue(status.status == .NotOK, "the status should be NotOK")
XCTAssertTrue(status.list.count == 2, "the list should have 2 items")
if status.list.count == 2 {
XCTAssertTrue(status.list[0]?.nullableType == 2, "the first item in the list should have nullableType 2")
XCTAssertTrue(status.list[1]?.nullableType == 3, "the second item in the list should have nullableType 3")
}
}
}
class Testobject: EVObject {
enum StatusType: Int {
case NotOK = 0
case OK
}
var nullableType: Int?
var status: StatusType = .OK
var list: [Testobject?] = []
override func setValue(value: AnyObject!, forUndefinedKey key: String) {
switch key {
case "nullableType":
nullableType = value as? Int
case "status":
if let rawValue = value as? Int {
status = StatusType(rawValue: rawValue)!
}
case "list":
if let list = value as? NSArray {
self.list = []
for item in list {
self.list.append(item as? Testobject)
}
}
default:
NSLog("---> setValue for key '\(key)' should be handled.")
}
}
}
Run Code Online (Sandbox Code Playgroud)
Jon*_*n N 14
当我想要解决类似问题时,我找到了解决这个问题的方法--KVO无法设置纯Swift协议字段的值.该协议必须标记为@objc,这在我的代码库中造成了太多的痛苦.解决方法是使用目标C运行时查找Ivar,获取字段偏移量,并使用指针设置值.此代码适用于Swift 2.2中的操场:
import Foundation
class MyClass
{
var myInt: Int?
}
let instance = MyClass()
// Look up the ivar, and it's offset
let ivar: Ivar = class_getInstanceVariable(instance.dynamicType, "myInt")
let fieldOffset = ivar_getOffset(ivar)
// Pointer arithmetic to get a pointer to the field
let pointerToInstance = unsafeAddressOf(instance)
let pointerToField = UnsafeMutablePointer<Int?>(pointerToInstance + fieldOffset)
// Set the value using the pointer
pointerToField.memory = 42
assert(instance.myInt == 42)
Run Code Online (Sandbox Code Playgroud)
笔记:
编辑:现在有一个名为Runtime的框架,位于https://github.com/wickwirew/Runtime,它提供了Swift 4+内存布局的纯Swift模型,允许它安全地计算ivar_getOffset的等价物,而无需调用Obj C运行时.这允许设置如下属性:
let info = try typeInfo(of: User.self)
let property = try info.property(named: "username")
try property.set(value: "newUsername", on: &user)
Run Code Online (Sandbox Code Playgroud)
这可能是一个很好的方法,直到等效功能成为Swift本身的一部分.
| 归档时间: |
|
| 查看次数: |
6727 次 |
| 最近记录: |