Why does the debugger 'po' works with 'var' vs 'let'? - swift

Why does the debugger 'po' works with var:
var myDict = currentImageDownloader.dict
As shown here:
(lldb) po myDict
Some
{
[0] = {
key = "ispublic"
value = (instance_type = Builtin.RawPointer = 0xb000000000000013)
(lldb) po myDict
error: <EXPR>:1:1: error: use of unresolved identifier 'myDict'
myDict
...
yet via 'let':
let myDict = currentImageDownloader.dict
The debugger 'po' doesn't work:
(lldb) po myDict
error: <EXPR>:1:1: error: use of unresolved identifier 'myDict'
myDict
^
Although I can view everything via 'let' or 'var' using the debugger's frame command:
(lldb) fr v
(UICollectionView) collectionView = 0x00007fc2d2821600 {
UIKit.UIScrollView = {
UIKit.UIView = {
UIKit.UIResponder = {
ObjectiveC.NSObject = {}
}
}
}
}
(NSIndexPath) indexPath = 0xc000000000000016 {
ObjectiveC.NSObject = {}
}
(FlickrSwift.ViewController) self = 0x00007fc2d2580f20 {
UIKit.UIViewController = {
UIKit.UIResponder = {
ObjectiveC.NSObject = {}
}
}
collectionView = Some
}
(FlickrSwift.ImageDownloader) currentImageDownloader = 0x00007fc2d4449750 {
image = nil
bigImage = nil
dict = Some {
[0] = {
key = "ispublic"
value = (instance_type = Builtin.RawPointer = 0xb000000000000013)
}
[1] = {
key = "height_sq"
value = (instance_type = Builtin.RawPointer = 0xb0000000000004b3)
}
[2] = {
key = "url_m"
value = (instance_type = Builtin.RawPointer = 0x00007fc2d25131a0 -> 0x00000001088e7488 (void *)0x00000001088e7438: __NSCFString)
}
[3] = {
key = "title"
value = (instance_type = Builtin.RawPointer = 0x00007fc2d25a7030 -> 0x00000001088e7488 (void *)0x00000001088e7438: __NSCFString)
}
[4] = {
key = "isfamily"
value = (instance_type = Builtin.RawPointer = 0xb000000000000003)
}
...
}
descString = nil
}
(AnyObject) cell = <variable not available>
(UIImageView) photoImageView = <variable not available>
(UIImage) image = <variable not available>

There were a couple of bugs in the debug information for "let" variables that kept lldb from being able to understand them correctly. These should all be fixed in the upcoming Xcode release. You'll need to recompile your code once you get the new release, but after that you should be able to see them.
If you aren't please file a bug with http://bugreporter.apple.com.

Related

Why is the app crashing when doing a Fetch Request in Core Data

Core Data is crashing when doing a fetch request but I can't understand why. The error is suggesting EXC_BAD_ACCESS but it doesn't always occur for this particular fetch request. Basically when I zoom in and out on the mapView (MKMapKit), it's at that point it crashes.
For my mapView I use the following code:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let userStatus = CoreDataUserLocationManagement().returnUsersLastKnownStatus()
if (annotation is MKUserLocation) && userStatus != 3 {
As you can see from the above, this is when I request the lastKnownStatus, but as mentioned it doesn't always crash.
This fetch crashes here
func returnUsersLastKnownStatus() -> Int16 {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "UsersLocationDetails")
do {
if let fetchResults = try managedObjectContext.fetch(fetchRequest) as? [UsersLocationDetails] {
if fetchResults.count != 0 {
let managedObject = fetchResults[0]
return managedObject.lastKnownStatus
}
}
}
catch {
print("Catch error retrieving last known status to Core Data")
}
return 3
}
The log is:
Printing description of fetchRequest:
(NSFetchRequest) fetchRequest = 0x0000000283a5be20 {
baseNSPersistentStoreRequest#0 = {
baseNSObject#0 = {
isa = NSFetchRequest
}
_affectedStores = 0x0000000000000000
}
_groupByProperties = 0x0000000000000000
_havingPredicate = 0x0000000000000000
_additionalPrivateIvars = 0x0000000281044100
_valuesToFetch = 0x0000000000000000
_entity = 0x0000000282684dc0 {
baseNSObject#0 = {
isa = NSEntityDescription
}
_cd_rc = 12
_snapshotClass = 0x000000028208a760
_versionHashModifier = 0x0000000000000000
_versionHash = some {
some = 0x0000000102faea90 {
baseNSData#0 = {
baseNSObject#0 = {
isa = _PFEncodedData
}
}
_aData = some {
some = 0x00000002811c7e60 {
baseNSData#0 = {
baseNSObject#0 = {
isa = _PFVMData
}
}
_cd_rc = 1732
_length = 40944
_payload = 0x0000000102fac000
}
}
_byteCount = 32
_reserved = 0
}
}
_model = some {
some = 0x00000002832a9400 {
baseNSObject#0 = {
isa = NSManagedObjectModel
}
_dataForOptimization = some {
some = 0x00000002811c7e60 {...}
}
_optimizationHints = 0x0000000102fb5850
_additionalPrivateIvars = 0x00000002811c0120
_entities = some {
some = 0x000000028239f9f0 {
baseNSKnownKeysDictionary1#0 = {
baseNSKnownKeysDictionary#0 = {
baseNSMutableDictionary#0 = {
NSDictionary = {
NSObject = {
isa = NSKnownKeysDictionary2
}
}
}
}
_cd_rc = 0
_count = 14
_keySearch = some {
some = 0x0000000102faeb10 {
baseNSKnownKeysMappingStrategy1#0 = {
baseNSKnownKeysMappingStrategy#0 = {
baseNSObject#0 = {
isa = NSKnownKeysMappingStrategy2
}
}
_cd_rc = -2128839072
_reserved64 = 2
_table = 0x0000000102faeb40
_length = 14
_reserved1 = 0x0000000000000000
_keys = 0x0000000102faec28
}
}
}
_values = {}
}
}
}
_configurations = 0x00000002811c0100 1 key/value pair
_fetchRequestTemplates = 0x0000000000000000
_versionIdentifiers = 0x00000002811c0140 1 element
}
}
_classNameForEntity = some {
some = 0x0000000102fad388 {
base_PFAbstractString#0 = {
baseNSString#0 = {
baseNSObject#0 = {
isa = _PFEncodedString
}
}
}
_cd_rc = 0
_length = 20
_sourceData = some {
some = 0x00000002811c7e60 {...}
}
}
}
_instanceClass = 0x00000002835b9b70
_name = some {
some = 0x0000000102fad388 {...}
}
_rootentity = 0x0000000282684dc0 {...}
_superentity = 0x0000000000000000
_subentities = 0x0000000000000000
_properties = some {
some = 0x00000002835b8720 {
baseNSKnownKeysDictionary1#0 = {
baseNSKnownKeysDictionary#0 = {
baseNSMutableDictionary#0 = {
NSDictionary = {
NSObject = {
isa = NSKnownKeysDictionary2
}
}
}
}
_cd_rc = 0
_count = 9
_keySearch = some {
some = 0x0000000102fb0bf0 {
baseNSKnownKeysMappingStrategy1#0 = {
baseNSKnownKeysMappingStrategy#0 = {
baseNSObject#0 = {
isa = NSKnownKeysMappingStrategy2
}
}
_cd_rc = -2128839072
_reserved64 = 2
_table = 0x0000000102fb0c20
_length = 9
_reserved1 = 0x0000000000000000
_keys = 0x0000000102fb0cd0
}
}
}
_values = {}
}
}
}
_propertyMapping = some {
some = 0x0000000102fb0bf0 {...}
}
_userInfo = 0x0000000000000000
_flattenedSubentities = 0x0000000281ff60d0 1 element
_kvcPropertyAccessors = 0x00000002832a92c0
_modelsReferenceIDForEntity = 13
}
_predicate = 0x0000000000000000
_sortDescriptors = 0x0000000000000000
_batchSize = 0
_fetchLimit = 0
_allocationSize = 0
_relationshipKeyPathsForPrefetching = 0x0000000000000000
}
Also just noticed this in Xcode:
(NSPersistentStoreRequest) CoreData.NSPersistentStoreRequest = <parent failed to evaluate: invalid load address>
So it turns out that it was this piece of code that code that was causing the issue. I have no idea why as the crash wasn't reporting this but as soon as I commented it out, it no longer crashes.
#IBAction func centerUserBtnTapped(_ sender: Any) {
let location = CLLocationCoordinate2D(latitude: locationManager.location?.coordinate.latitude ?? 0.0, longitude: locationManager.location?.coordinate.longitude ?? 0.0)
let span = MKCoordinateSpan.init(latitudeDelta: self.mapView.region.span.latitudeDelta, longitudeDelta: self.mapView.region.span.longitudeDelta)
let region = MKCoordinateRegion(center: location, span: span)
self.mapView.setRegion(region, animated: true)
self.mapView.setUserTrackingMode(.follow, animated: true)
}
Instead I simplified it to the normal approach:
#IBAction func centerUserBtnTapped(_ sender: Any) {
mapView.setUserTrackingMode(.follow, animated: true)
}

Why Memory leaks when initialize array of dictionary in class?

It's my class initializer:
typealias JSONDictionaty = [String: AnyObject]
private var _conditions: [[String: String]]?
init(data: JSONDictionaty) {
if let conditions = data["conditions"] as? [JSONDictionaty] {
if conditions.count > 0 {
self._conditions = [[:]] // init _condition
}
// adding all conditions to _condition variable
for condition in conditions {
if let subCond = condition as? [String: String] ,
type = subCond["type"],
expression = subCond["expression"] {
self._conditions?.append([type: expression])
}
}
}
/// deinit _condition variable
if self._conditions?.count == 0 {
self._conditions = nil
}
}
}
I have leaks on this lines:
if let type = subCond["type"], expression = subCond["expression"] {
self._conditions?.append([type: expression])
}
but if I change above lines to this line, memory leaks will be gone:
self._conditions?.append(subCond)

How to get a value from a complicated dictionary?

An API returns this response below but I don't know how to parse it.
Response JSON
[
"results": [
[
"address": "mgG2W14th6TXYWXNDrZ24shsJ2wYhJm2b3",
"total": [
"balance": 0,
"received": 0,
"sent": 0
],
"confirmed": [
"balance": 0,
"received": 0,
"sent": 0
]
]
]
]
Swift Code
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.chain!.getAddress(address!) { dictionary, error in
NSLog("%#", dictionary)
}
Dictionary Object
(lldb) po dictionary
[results: (
{
address = mgG2W14th6TXYWXNDrZ24shsJ2wYhJm2b3;
confirmed = {
balance = 0;
received = 0;
sent = 0;
};
total = {
balance = 0;
received = 0;
sent = 0;
};
}
)]
I tried it many times... Can you share how to fix it please..
(lldb) po dictionary["results"]![0]
{
address = mgG2W14th6TXYWXNDrZ24shsJ2wYhJm2b3;
confirmed = {
balance = 0;
received = 0;
sent = 0;
};
total = {
balance = 0;
received = 0;
sent = 0;
};
}
po dictionary["results"]![0]!["address"]
error: <EXPR>:1:28: error: cannot subscript a value of type 'AnyObject' with an index of type 'String'
dictionary["results"]![0]!["address"]
I got "Could not find member 'subscript'" at "let address = ..." line.
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.chain!.getAddress(address!) { dictionary, error in
NSLog("%#", dictionary)
let address = dictionary["results"]![0]["address"]!
print("address: \(address)")
}
if let myDictionary = dictionary as? [String:AnyObject] {
if let results = myDictionary["results"] as? [AnyObject] {
if let firstItem = results[0] as? [String: AnyObject] {
if let address = firstItem["address"] as? String {
print(address)
}
if let total = firstItem["total"] as? [String:Int] {
if let balance = total["balance"] {
print(balance)
}
if let received = total["received"] {
print(received)
}
if let sent = total["sent"] {
print(sent)
}
}
if let confirmed = firstItem["confirmed"] as? [String:Int] {
if let balance = confirmed["balance"] {
print(balance)
}
if let received = confirmed["received"] {
print(received)
}
if let sent = confirmed["sent"] {
print(sent)
}
}
}
}
}
In order to simplify things you can create a class which will be managing such parsing if the data returned always has the same format.

extension of Int needs an explicit call to init

I am creating an extension of Int with my own init but I cannot use the init implicitly. Can somebody please explain why? I can however call the init explicitly as shown below.
extension Int {
init?(fromHexString: String) {
let HexRadix:Int = 16
let DigitsString = "0123456789abcdefghijklmnopqrstuvwxyz"
let digits = DigitsString
var result = Int(0)
for digit in fromHexString.lowercaseString {
if let range = digits.rangeOfString(String(digit)) {
let val = Int(distance(digits.startIndex, range.startIndex))
if val >= Int(HexRadix) {
return nil
}
result = result * Int(HexRadix) + val
} else {
return nil
}
}
self = result
}
}
let firstString = "ff"
//This works
let parsedInt:Int = Int.init(fromHexString: firstString)!
println("\(parsedInt)")
//But this does not ; Error: Int is not identical to Int? Why??
let parsedInt1:Int = Int(fromHexString: firstString)!
println("\(parsedInt1)")

How do I property dissect/disseminate a Dictionary with an Array?

I'm trying to disseminate the response of a NSJSONSerialization:
let responseDict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &jsonError) as NSDictionary
So far, I have a good output which I want to dissect/disseminate:
(lldb) po responseDict
{
photos = {
page = 1;
pages = 1333;
perpage = 100;
photo = (
{
farm = 4;
"height_m" = 243;
"height_s" = 117;
"height_sq" = 75;
"height_t" = 49;
id = 15148883617;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "48531100#N04";
secret = fb6596ca90;
server = 3926;
title = "An Exceptional Roman Orichalcum Sestertius of Nero (54-68 C.E.), a Magnificent Depiction of the Temple of Janus on the Reverse";
"url_m" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90.jpg";
"url_s" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_m.jpg";
"url_sq" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_s.jpg";
"url_t" = "https://farm4.staticflickr.com/3926/15148883617_fb6596ca90_t.jpg";
"width_m" = 500;
"width_s" = 240;
"width_sq" = 75;
"width_t" = 100;
},
...
...
The problem is doing the dissemination.
Here's the contents of "photos" key (rather ugly compared to the ObjC counterpart):
(lldb) po responseDict["photos"]
(instance_type = Builtin.RawPointer = 0x00007fce90ec74e0 -> 0x0000000105a910e0 (void *)0x0000000105a91220: __NSDictionaryM)
{
instance_type = 0x00007fce90ec74e0 -> 0x0000000105a910e0 (void *)0x0000000105a91220: __NSDictionaryM
}
This line produces a fatal (dynamic cast) crash:
let myPhotos = responseDict["photos"] as NSArray
Here's an ObjC equivalent (that works):
jsonDict[#"photos"][#"photo"];
Compare that to the following Swift equivalent that gives me an error (even though I had downcast it to NSDictionary):
(lldb) po responseDict["photos"]["photo"]
error: <EXPR>:1:1: error: 'AnyObject?' does not have a member named 'subscript'
responseDict["photos"]["photo"]
Question: How do I properly dissect a dictionary (or any collection) in Swift as I can in Objective-C?
I managed to get down to the individual dictionary:
let myPhotos = responseDict["photos"] as? NSDictionary
let photos = myPhotos!["photo"] as? NSArray
let myPhoto:AnyObject = photos![0]
println(myPhoto)
Here's the output:
{
farm = 4;
"height_m" = 500;
"height_s" = 240;
"height_sq" = 75;
"height_t" = 100;
id = 15150188169;
isfamily = 0;
isfriend = 0;
ispublic = 1;
owner = "87355413#N02";
secret = e9cfed5225;
server = 3905;
title = "Miss 18mths wearing Music Box pinafore in grey denim (18-24mths). Trimmed with aqua/pink ric rac, and \"bow\" button.";
"url_m" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225.jpg";
"url_s" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_m.jpg";
"url_sq" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_s.jpg";
"url_t" = "https://farm4.staticflickr.com/3905/15150188169_e9cfed5225_t.jpg";
"width_m" = 375;
"width_s" = 180;
"width_sq" = 75;
"width_t" = 75;
}
And to test it further:
let myPhoto = myPhotoInfo["url_m"] as String
Produces:
https://farm4.staticflickr.com/3920/15333895891_956d072454.jpg
From the Objective-C code that works it appears that responseDict["photos"] is not an NSArray, it is NSDictionary. This should work:
let myPhotos = responseDict["photos"] as? NSDictionary
let photo = myPhotos!["photo"]