I created a Serializable Protocol that turns a object in a [String:AnyObject]
object (JSON format) using reflection, but I'm getting a leak warning when type casting/checking in Swift 2.1.
I already knows that Swift has some memory leaks problems, as related in the SwifityJSON project (link: http://ift.tt/1MF3ksh), but I couldn't get my code to work without the leaks.
I'm using Xcode 7.1.1 (7B1005) and Swift 2.1, my deployment target is 8.0 and the app is running in the Iphone 5 simulator.
Someone knows any workaround or solution to this? Maybe I'm doing something wrong. My code: (just add the code to a project and call test function with leaks profile):
public class testB: Serializable {
let a:Int
let b:Int?
public init() {
a = 1
b = nil
}
}
public class testA : Serializable {
let a:String
let b:Double
var c:[String:Serializable]
var d:[Double]
var e:[String:String]
public init() {
a = "teste"
b = 1.2
c = [String:Serializable]()
c["teste"] = testB()
d = [Double()]
d[0] = 3.5
e = [String:String]()
e["teste"] = "teste"
}
}
public func test() {
testA().toDictionary()
}
public protocol Serializable {
}
extension Serializable {
func getValue(unknownValue:Any) -> Any? {
let mi = Mirror(reflecting: unknownValue)
if mi.displayStyle != .Optional {
return unknownValue
}
if mi.children.count == 0 {
return nil
}
let (_, some) = mi.children.first!
return some
}
//Memory Leak happens here.
func toDictionary() -> [String:AnyObject] {
var result = [String:AnyObject]()
let serializableMirror = Mirror(reflecting: self)
for childMirror in serializableMirror.children {
let label = childMirror.label
if let value = self.getValue(childMirror.value) {
if let x = value as? NSData {
result[label!] = x.base64EncodedDataWithOptions(.Encoding64CharacterLineLength)
} else if let x = value as? NSDate {
result[label!] = x.timeIntervalSince1970
} else if let x = value as? Serializable {
result[label!] = x.toDictionary()
} else if let x = value as? [NSData] {
var newArray = [NSData]()
for xItem in x {
newArray.append(xItem.base64EncodedDataWithOptions(.Encoding64CharacterLineLength))
}
result[label!] = newArray
} else if let x = value as? [NSDate] {
var newArray = [NSTimeInterval]()
for xItem in x {
newArray.append(xItem.timeIntervalSince1970)
}
result[label!] = newArray
} else if let x = value as? [Serializable] {
var newArray = [[String:AnyObject]]()
for xItem in x {
newArray.append(xItem.toDictionary())
}
result[label!] = newArray
} else if let x = value as? [String:NSData] {
var newDictionary = [String:NSData]()
for (y,z) in x {
newDictionary[y] = z.base64EncodedDataWithOptions(.Encoding64CharacterLineLength)
}
result[label!] = newDictionary
} else if let x = value as? [String:NSDate] {
var newDictionary = [String:NSTimeInterval]()
for (y,z) in x {
newDictionary[y] = z.timeIntervalSince1970
}
result[label!] = newDictionary
} else if let x = value as? [String:Serializable] {
var newDictionary = [String:[String:AnyObject]]()
for (y,z) in x {
newDictionary[y] = z.toDictionary()
}
result[label!] = newDictionary
} else if value is NSNumber || value is String
|| value is [Bool] || value is [Int] || value is [Double] || value is [Float] || value is [String]
|| value is [String:Bool] || value is [String:Int] || value is [String:Double] || value is [String:Float] || value is [String:String] {
if let x = value as? AnyObject {
result[label!] = x
}
}
}
}
return result
}
}
The leaks message.
Aucun commentaire:
Enregistrer un commentaire