Swift EXC_BAD_ACCESS with a corrupted object? - swift

For some strange reason, I'm encountering an EXC_BAD_ACCESS, specifically in unwrapping and referencing a field. (Reproducible on the Xcode 7 GM.)
Here's the relevant code:
// FIXME: BUGGY
let conv_id = client_conversation.conversation_id //!.id
print("ABOUT TO DIE: \(conv_id?.id)")
if conv_id!.id as? String != nil {
conv_id!.id = "hi"
}
It crashes at the print() statement. Not sure what I can adequately do to fix this. I've tried the malloc() debugging, Zombie objects, and hand-debugging via backtrace.
I've added the definition of these objects:
class Message : NSObject {
required override init() {
super.init()
}
}
class CONVERSATION_ID : Message {
var id: NSString = ""
}
class CLIENT_CONVERSATION : Message {
var conversation_id: CONVERSATION_ID?
var type = ConversationType()
var name: NSString?
var self_conversation_state = CLIENT_CONVERSATION_INTERNAL_STATE()
var read_state = [CLIENT_CONVERSATION_READ_STATE]()
var current_participant = [USER_ID]()
var participant_data = [CLIENT_CONVERSATION_PARTICIPANT_DATA]()
}
Another example issue: while print(conv_id!) prints
(
"sample string"
)
I can't seem to be able to access the string directly.

Any time you say ! you are inviting a crash. Rewrite your code so that ! never appears. Know your Optionals and unwrap every single one of them safely. Learn about how to compare an Optional with nil before unwrapping, or how to use the if let construct.
Also, note that this line is sheer nonsense (what I call a "false cast"):
if conv_id!.id as? String != nil {
An NSString is always a String; I am surprised that the compiler is not warning you about this. Thus, the test is meaningless.
Your code should therefore read like this:
let conv_id = client_conversation.conversation_id
conv_id?.id = "hi"
Notice that there are no false casts and exclamation marks.

Related

weird double-nullable variable error, why is it happening?

sometimes compiler produces weird optional error with double nullable operator like Value of optional type 'Data??' must be unwrapped to a value of type 'Data?', I'm wondering why is it happening? is this a bug or quirk I dont understand? Here's sample of code to reproduce
import Foundation
public class testClass {
var id: Int64?
init(id: Int64?, completionHandler: (([Data?], Bool) -> Data?)?) {
self.id = id
}
}
let tC = testClass(id: 1) { datas, val in
return datas.first
}
I'm not asking how to fix it, I'm just curious why this is happening as it looks like a bug for me - variable either exists or is nil
You are overcomplicating the issue with your example. All you need for demonstration is this, where Wrapped could be any type:
typealias Wrapped = Void
let optionals: [Wrapped?] = []
let wrapped: Wrapped? = optionals.first
What's actually going on in that last line, if you use the correct type, is this:
let doubleOptional: Wrapped?? = optionals.first
You need to provide a default value, for when the array is empty:
// `nil` is the same as Wrapped?.none, here.
let optional: Wrapped? = optionals.first ?? nil
And if it was safe to force-unwrap, then one ! would not be enough, either. You'd need two:
let wrapped: Wrapped = optionals.first!!
You should probably question why you have an array of optionals to begin with.

How to solve "String interpolation produces a debug description for an optional value; did you mean to make this explicit?" in Xcode 8.3 beta?

Since beta 8.3, zillions warnings "String interpolation produces a debug description for an optional value; did you mean to make this explicit?" appeared in my code.
For example, the warning popped in the following situation up, where options could lead to nil:
let msg = "*** Error \(options["taskDescription"]): cannot load \(sUrl) \(error)"
As previously designed, it was ok for me (and the compiler) the optionals to be interpolated as 'nil'. But compiler changed its mind.
What the compiler suggests is to add a String constructor with description as follows:
let msg = "*** Error \(String(describing: options["taskDescription"])): cannot load \(sUrl) \(error)"
Obviously, the results is explicit but also very very cumbersome in my opinion. Is there a better option? Do I have to fix all those warning or better wait for the next beta?
This is a change that was made in this pull request due to the fact that interpolating Optional(...) into the resultant string is often undesirable, and can be especially surprising in cases with implicitly unwrapped optionals. You can see the full discussion of this change on the mailing list here.
As mentioned in the pull request discussion (although unfortunately not by Xcode) – one slightly nicer way to silence the warning than the use of String(describing:) is to add a cast to the optional type of whatever you're interpolating, so for example:
var i: Int? = 5
var d: Double? = nil
print("description of i: \(i as Int?)") // description of i: Optional(5)
print("description of d: \(d as Double?)") // description of d: nil
Which can also be generalised to as Optional:
print("description of i: \(i as Optional)") // description of i: Optional(5)
print("description of d: \(d as Optional)") // description of d: nil
In Swift 5, with the new string interpolation system introduced by SE-0228, another option is to add a custom appendInterpolation overload for DefaultStringInterpolation:
extension DefaultStringInterpolation {
mutating func appendInterpolation<T>(optional: T?) {
appendInterpolation(String(describing: optional))
}
}
var i: Int? = 5
var d: Double? = nil
print("description of i: \(optional: i)") // description of i: Optional(5)
print("description of d: \(optional: d)") // description of d: nil
And, if desired, you could even remove the argument label to disable the warning entirely within a module (or within a particular file if you mark it as fileprivate):
extension DefaultStringInterpolation {
mutating func appendInterpolation<T>(_ optional: T?) {
appendInterpolation(String(describing: optional))
}
}
var i: Int? = 5
var d: Double? = nil
print("description of i: \(i)") // description of i: Optional(5)
print("description of d: \(d)") // description of d: nil
Though personally I would prefer to keep the argument label.
Two easier ways of dealing with this issue.
Option 1:
The first would be by "force-unwrapping" the value you would like to return using a bang (!)
var someValue: Int? = 5
print(someValue!)
Output:
5
Option 2:
The other way, which could be the better way - is to "safely-unwrap" the value you want returned.
var someValue: Int? = 5
if let newValue = someValue {
print(newValue)
}
Output:
5
Would recommend to go with option 2.
Tip: Avoid force unwrapping (!) where possible as we are not sure if we will always have the value to be unwrapped.
seems using String(describing:optional) is simplest.
default value ?? makes no sense for non-Strings e.g Int.
If Int is nil then you want the log to show 'nil' not default to another Int e.g. 0.
Some playground code to test:
var optionalString : String? = nil
var optionalInt : Int? = nil
var description_ = ""
description_ = description_ + "optionalString: \(String(describing: optionalString))\r"
description_ = description_ + " optionalInt: \(String(describing: optionalInt))\r"
print(description_)
Output
optionalString: nil
optionalInt: nil
After updating to Xcode 8.3 and getting a lot of warning messages, I came up with the following that is more like the original output behavior, easy to add in, reduces the verboseness of using "String(describing:)" both in code and output.
Basically, add an Optional extension that gives a String describing the thing in the optional, or simply "nil" if not set. In addition, if the thing in the optional is a String, put it in quotes.
extension Optional {
var orNil : String {
if self == nil {
return "nil"
}
if "\(Wrapped.self)" == "String" {
return "\"\(self!)\""
}
return "\(self!)"
}
}
And usage in a playground:
var s : String?
var i : Int?
var d : Double?
var mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = nil i = nil d = nil"
d = 3
i = 5
s = ""
mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = "" i = 5 d = 3.0"
s = "Test"
d = nil
mixed = "s = \(s.orNil) i = \(i.orNil) d = \(d.orNil)" // "s = "Test" i = 5 d = nil"
Thanks for help from following link:
check-if-variable-is-an-optional-and-what-type-it-wraps
See Ole Begeman's fix for this. I love it. It creates a ??? operator which you can then use like this:
var someValue: Int? = 5
print("The value is \(someValue ??? "unknown")")
// → "The value is 5"
someValue = nil
print("The value is \(someValue ??? "unknown")")
// → "The value is unknown"
Double click on the yellow triangle displayed on line containing this warning. This will show FixIt with two solutions.
Use String(describing:) to silence this warning :
Using this it will become String(describing:<Variable>)
Eg. : String(describing: employeeName)
Provide a default value to avoid this warning :
Using this it will become (<Variable> ?? default value)
Eg.: employeeName ?? “Anonymous” as! String
Swift 5
My solution is making an extension which unwrap Optional object to Any.
When you log the object or print it out, you can see the actual object or <nil>⭕️ (combination from text and visual character). It's useful to look at, especially in the console log.
extension Optional {
var logable: Any {
switch self {
case .none:
return "<nil>|⭕️"
case let .some(value):
return value
}
}
}
// sample
var x: Int?
print("Logging optional without warning: \(x.logable)")
// → Logging optional without warning: <nil>|⭕️
Create an interpolation method that accepts an optional generic Type with an unnamed parameter. All your annoying warnings will magically disappear.
extension DefaultStringInterpolation {
mutating func appendInterpolation<T>(_ optional: T?) {
appendInterpolation(String(describing: optional))
}
}

What am I overlooking as I attempt to account for nil?

I've reread the Swift documentation a number of times, but I'm afraid I'm overlooking something simple here.
The function below processes just fine and properly calls the updateCalorieBalance method if there is value in the field caloriesConsumed.text. But, of course, crashes if caloriesConsumed.text is nil.
The error message I get is: fatal error: unexpectedly found nil while unwrapping an Optional value.
Your assistance is greatly appreciated.
#IBAction func buttonThree(sender: AnyObject) {
var calConsumed: String?
if let calConsumed = caloriesConsumed.text {
calorieCount.updateCalorieBalance(Double(calConsumed)!)
balanceLabel.text = "New Balance: \(Int((calorieCount.getCalorieBalance())))"
} else {
balanceLabel.text = "Please enter calories to add."
}
caloriesConsumed.resignFirstResponder()
}
calConsumed should not be an optional string. Actually, "if let" creates its own variable so you now have two variables with the same name...
Double (calConsumed) returns nil if calConsumed is an empty string or a string not containing a number. The ! that you use will make it crash.
if let calText = caloriesConsumed.text,
calNumber = Double (calText) {
...
}
(Not tested or even compiled).

Printing optional variable

I am trying with these lines of code
class Student {
var name: String
var age: Int?
init(name: String) {
self.name = name
}
func description() -> String {
return age != nil ? "\(name) is \(age) years old." : "\(name) hides his age."
}
}
var me = Student(name: "Daniel")
println(me.description())
me.age = 18
println(me.description())
Above code produces as follow
Daniel hides his age.
Daniel is Optional(18) years old.
My question is why there is Optional (18) there, how can I remove the optional and just printing
Daniel is 18 years old.
You have to understand what an Optional really is. Many Swift beginners think var age: Int? means that age is an Int which may or may not have a value. But it means that age is an Optional which may or may not hold an Int.
Inside your description() function you don't print the Int, but instead you print the Optional. If you want to print the Int you have to unwrap the Optional. You can use "optional binding" to unwrap an Optional:
if let a = age {
// a is an Int
}
If you are sure that the Optional holds an object, you can use "forced unwrapping":
let a = age!
Or in your example, since you already have a test for nil in the description function, you can just change it to:
func description() -> String {
return age != nil ? "\(name) is \(age!) years old." : "\(name) hides his age."
}
To remove it, there are three methods you could employ.
If you are absolutely sure of the type, you can use an exclamation mark to force unwrap it, like this:
// Here is an optional variable:
var age: Int?
// Here is how you would force unwrap it:
var unwrappedAge = age!
If you do force unwrap an optional and it is equal to nil, you may encounter this crash error:
This is not necessarily safe, so here's a method that might prevent crashing in case you are not certain of the type and value:
Methods 2 and three safeguard against this problem.
The Implicitly Unwrapped Optional
if let unwrappedAge = age {
// continue in here
}
Note that the unwrapped type is now Int, rather than Int?.
The guard statement
guard let unwrappedAge = age else {
// continue in here
}
From here, you can go ahead and use the unwrapped variable. Make sure only to force unwrap (with an !), if you are sure of the type of the variable.
Good luck with your project!
For testing/debugging purposes I often want to output optionals as strings without always having to test for nil values, so I created a custom operator.
I improved things even further after reading this answer in another question.
fileprivate protocol _Optional {
func unwrappedString() -> String
}
extension Optional: _Optional {
fileprivate func unwrappedString() -> String {
switch self {
case .some(let wrapped as _Optional): return wrapped.unwrappedString()
case .some(let wrapped): return String(describing: wrapped)
case .none: return String(describing: self)
}
}
}
postfix operator ~? { }
public postfix func ~? <X> (x: X?) -> String {
return x.unwrappedString
}
Obviously the operator (and its attributes) can be tweaked to your liking, or you could make it a function instead. Anyway, this enables you to write simple code like this:
var d: Double? = 12.34
print(d) // Optional(12.34)
print(d~?) // 12.34
d = nil
print(d~?) // nil
Integrating the other guy's protocol idea made it so this even works with nested optionals, which often occur when using optional chaining. For example:
let i: Int??? = 5
print(i) // Optional(Optional(Optional(5)))
print("i: \(i~?)") // i: 5
Update
Simply use me.age ?? "Unknown age!". It works in 3.0.2.
Old Answer
Without force unwrapping (no mach signal/crash if nil) another nice way of doing this would be:
(result["ip"] ?? "unavailable").description.
result["ip"] ?? "unavailable" should have work too, but it doesn't, not in 2.2 at least
Of course, replace "unavailable" with whatever suits you: "nil", "not found" etc
To unwrap optional use age! instead of age. Currently your are printing optional value that could be nil. Thats why it wrapped with Optional.
In swift Optional is something which can be nil in some cases. If you are 100% sure that a variable will have some value always and will not return nil the add ! with the variable to force unwrap it.
In other case if you are not much sure of value then add an if let block or guard to make sure that value exists otherwise it can result in a crash.
For if let block :
if let abc = any_variable {
// do anything you want with 'abc' variable no need to force unwrap now.
}
For guard statement :
guard is a conditional structure to return control if condition is not met.
I prefer to use guard over if let block in many situations as it allows us to return the function if a particular value does not exist.
Like when there is a function where a variable is integral to exist, we can check for it in guard statement and return of it does not exist.
i-e;
guard let abc = any_variable else { return }
We if variable exists the we can use 'abc' in the function outside guard scope.
age is optional type: Optional<Int> so if you compare it to nil it returns false every time if it has a value or if it hasn't. You need to unwrap the optional to get the value.
In your example you don't know is it contains any value so you can use this instead:
if let myAge = age {
// there is a value and it's currently undraped and is stored in a constant
}
else {
// no value
}
I did this to print the value of string (property) from another view controller.
ViewController.swift
var testString:NSString = "I am iOS Developer"
SecondViewController.swift
var obj:ViewController? = ViewController(nibName: "ViewController", bundle: nil)
print("The Value of String is \(obj!.testString)")
Result :
The Value of String is I am iOS Developer
Check out the guard statement:
for student in class {
guard let age = student.age else {
continue
}
// do something with age
}
When having a default value:
print("\(name) is \(age ?? 0) years old")
or when the name is optional:
print("\(name ?? "unknown") is \(age) years old")
I was getting the Optional("String") in my tableview cells.
The first answer is great. And helped me figure it out. Here is what I did, to help the rookies out there like me.
Since I am creating an array in my custom object, I know that it will always have items in the first position, so I can force unwrap it into another variable. Then use that variable to print, or in my case, set to the tableview cell text.
let description = workout.listOfStrings.first!
cell.textLabel?.text = description
Seems so simple now, but took me a while to figure out.
This is not the exact answer to this question, but one reason for this kind of issue.
In my case,
I was not able to remove Optional from a String with "if let" and "guard let".
So use AnyObject instead of Any to remove optional from a string in swift.
Please refer link for the answer.
https://stackoverflow.com/a/51356716/8334818
If you just want to get rid of strings like Optional(xxx) and instead get xxx or nil when you print some values somewhere (like logs), you can add the following extension to your code:
extension Optional {
var orNil: String {
if self == nil {
return "nil"
}
return "\(self!)"
}
}
Then the following code:
var x: Int?
print("x is \(x.orNil)")
x = 10
print("x is \(x.orNil)")
will give you:
x is nil
x is 10
PS. Property naming (orNil) is obviously not the best, but I can't come up with something more clear.
With the following code you can print it or print some default value. That's what XCode generally recommend I think
var someString: String?
print("Some string is \(someString ?? String("Some default"))")
If you are printing some optional which is not directly printable but has a 'to-printable' type method, such as UUID, you can do something like this:
print("value is: \(myOptionalUUID?.uuidString ?? "nil")")
eg
let uuid1 : UUID? = nil
let uuid2 : UUID? = UUID.init()
print("uuid1: \(uuid1?.uuidString ?? "nil")")
print("uuid2: \(uuid2?.uuidString ?? "nil")")
-->
uuid1: nil
uuid2: 0576137D-C6E6-4804-848E-7B4011B40C11

is the init method not working properly in swift

With the code below, the local songs variable is never able to be iterated despite all the checks to the contrary ( println shows the value stored ). The other thing is that the Xcode debugger seems to jump all over the place in the init method.
let gLibraryManager = LibraryManager()
class LibraryManager {
var Songs = Dictionary<String, String>()
init() {
println("struct being initialized from NSDefaults")
let userDefaults = NSUserDefaults.standardUserDefaults();
var result:AnyObject = userDefaults.objectForKey(LIKED_LIST)
println(result)
var local = result as? Dictionary<String,String>
if local != nil {
println("local not nil: \(local!)")
for (id,title) in local! {
Songs[id] = title
}
if Songs.count > 0 {
println("NSDefaults detected: \(Songs)")
} else {
println("no NSDefaults detected. Initializing empty")
}
}
}
ok. i figured out what is was.
I had set the Swift Compiler - Code Generation. Optimization level to -Fastest. This was to prevent the extremely slow creation of Dictionaries.
However, it appears this breaks the ability to iterate structures.
It also seems to resolve the weird bouncing around of breakpoints.
This was a needle in a haystack that tooks many hours. I guess the moral of the story is not to mess with compiler flags yet.