How can I clear the swift warning "will never be excuted"? - swift

Now I am learning the swift and when I use the if - else ,the Xcode shows me a warniing "will not be excuted".Though it isn't a big problem, I don't want to see this, how can I clear this warning in the project?

This is from a logic error that the compiler has picked up and is warning you about.
It gives the line number in your code that can never be reached.
a) Change the logic of your code
b) delete or comment out lines of code that can never be reached
The compiler will not give this message unnecessarily
example
if 1 == 2 {
a = 3
}
else {
a = 4
}
Obviously the condition is never met, the a=3 assignment can never happen.

let a = 3;
let b = 4;
if (a == 3) {
print("executed")
} else if (a == 5) {
print("never be executed")
} else {
print("not executed")
}

Apple's LLVM compiler is pretty verbose when it tells you about warnings - if you check the logs you would find something like:
warning: will never be executed [-Wunreachable-code]
So to suppres that warning, you need to set the flag -Wno-unreachable-code. This works for the ObjC compiler, but currently isn't supported by the Swift compiler

Related

Confused about Optional vs Default value -1

We are working in a Swift project. A function was there like,
fun getSleepAmmount() -> Int {
// calculate sleep time
// return value when valid
// else
return -1
}
My team member prefers the above function where caller needs to check with -1 which is not I am comfortable with. My suggestion is to redesign with nil return (although callers still need to check nullability) like,
fun getSleepAmmount() -> Int? {
// calculate sleep time
// return value when valid
// else
return nil
}
But my colleagues do not want to redesign. Which version of the functions is cleaner and why?
Obviously, nil is much cleaner. Because of -1 means nothing. This is just a magic word. It is difficult to support, refactor and handle this case.
Returning nil is a better solution instead of using any garbage or default value.
Returning any default value may in future clash with the actual result.
Also, there might be other developers dealing with the same code. So, using nil will have a better explanation than using -1.
Second is the better as youll do
if let v = getSleepAmmount() {}
But with First
let v = getSleepAmmount()
if v > 0 {}
Returning nil means this isn't a valid return while -1 may mean another thing that will be miss-understood by a new developer that checks the code
If there is code in the caller that should only run if there is a valid sleep amount, then optionals is the better and clearer way to go. This is exactly what guard let and if let are designed for:
guard let sleepAmount = getSleepAmount() { else return }
// do something with sleepAmount
An even better way would be to throw an error inside the function:
func getSleepAmmount() throws -> Int {
// calculate sleep time
// return when valid
// else
throw InvalidSleepAmount
}
Then
do {
let sleepAmount = try getSleepAmount()
// do something with it
} catch InvalidSleepAmount {
// error processing
}
(If you want, your function could throw different errors so the caller gets to know why the sleep amount is invalid, SleepTooShort, SleepTooLong, NoSleep etc)

Swift Guard-Let Statement snippet

Why autocomplete for guardlet snippet doesn't work in closures? For example:
DispatchQueue.main.async(execute: {
guardlet //no any suggestions by Xcode
})
Shouldn't I use this control statement in any closure? Or it's just wrong scopes in the snippet?
I'm using Xcode 8.2 (8C38).
It works in Xcode 8.2.1:
Make sure you do not have pending compilation errors in your project.
You can close Xcode and reopen it eventually.
DispatchQueue.main.async(execute: {
guard let x = x where x > 0 else {
// Value requirements not met, do something
}
})
N.B:- Hi,there are no such key available "guardlet" in xcode please write that code"guard let"

How to stop ´enumerateChildNodesWithName("//*") ´ enumeration?

How do I stop this enumeration? I have the following code and Xcode complaining that I cannot assign a value to let constant. Stopping is probably a simple thing but I'm quite the noobie with Swift, so please bear with me.
self.enumerateChildNodesWithName("//*") {
spaceshipNode, stop in
if (( spaceshipNode.name?.hasSuffix("ship") ) != nil) {
for enemyNode in self.children {
if (enemyNode.name == "enemy"){
if(enemyNode.containsPoint(spaceshipNode.position)){
self.gotoGameOverScene(spaceshipNode)
stop = true // Error: Cannot assign to value: 'stop' is a 'let' constant
}
}
}
}
}
Generally you'd better show your code as text. With which we can easily copy & paste, and test it, or edit it.
In your code, the type of stop should be shown as UnsafeMutablePointer<ObjCBool> in the Quick Help pane of Xcode.
You need to modify the content of the pointer, in Swift2:
stop.memory = true
In Swift 3, the property memory is renamed to pointee:
stop.pointee = true
Apple's documentation suggests that we stop enumeration via stop.initialize(to: true).

Creating a calculator app

So I'm very new to Swift and have been following this tutorial to make this app https://www.youtube.com/watch?v=NJHsdjH2HdY
This was the first problem: currentNumber = currentNumber * 10 + Float(sender.titleLabel!.text!.toInt()!)
In the comments section the guy said to change that line to:
currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel!.text!)!)
I did this and I get the error: Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
As said in the comments, you should always avoid using the 'crash operator' (!) – and learn to safely deal with optional values instead.
Your program is crashing because either the titleLabel, text or Int(...) are nil – and you are then trying to force unwrap them. This could mean that your button doesn't have a titleLabel or that titleLabel's text isn't convertible to an Int.
The solution is to safely deal with the optionals as you encounter them. There are many ways of doing this, but I usually like to use one or multiple guard statements. This allows you to safely unwrap an optional if it has a value, otherwise it will execute the code within the brackets. This is useful for when future code depends on the optional not being nil. For example:
guard let buttonText = sender.titleLabel?.text else {
print("Sender didn't have either a titleLabel or text!")
return
}
guard let textAsInt = Int(buttonText) else {
print("Text wasn't convertible to an Int!")
return
}
currentNumber = currentNumber*10 + Float(textAsInt)
Now you get helpful print messages instead of crashes! Therefore you know exactly what went wrong, and what you can do to fix it (if it needs fixing).
You could also consolidate both of these checks into a single guard if you want more concise code, but less precise errors:
guard let buttonText = sender.titleLabel?.text, textAsInt = Int(buttonText) else {
print("Something went wrong when converting the button title to an Int!")
return
}
currentNumber = currentNumber*10 + Float(textAsInt)
Or you can use flatMap if you like closures:
guard let i = sender.titleLabel?.text.flatMap({Int($0)}) else {
print("Something went wrong when converting the button title to an Int!")
return
}
currentNumber = currentNumber*10 + Float(i)
The flatMap option can look a bit weird at first, but all it's doing is attempting to convert the button's titleLabel's text to an Int. If it fails it will return nil (which the guard will pick up), else it will return the numerical value of the text.
As #vacawama said in the comments, you could also use the nil coalescing operator in order to use 0 in the event that the titleLabel, text or Int(...) are nil:
currentNumber = currentNumber * 10 + Float(Int(sender.titleLabel?.text ?? "") ?? 0)
However bear in mind that this could lead to unexpected behaviour. I suspect that your program is crashing because your logic is getting run for non-numerical buttons, for example the "+" button. If this is the case, you'll be multiplying your number by 10 every time you press a non-numerical button. You'd have to first ensure that your logic only gets called on numerical buttons.
Although without seeing your full code, it's hard to say for sure.
For more info about how to safely deal with optionals, see this extensive Q&A on the subject.

Command failed due to signal: Segmentation fault: 11 | Xcode 7.2

I was asked to migrate a rather large app to Swift 2. The compiler keeps throwing segmentation fault: 11 errors for one function, present in different modules of the app's logic (only difference being variables used):
func loadMoreContent() {
if let collection = self.ratingsCollection where collection.identifier != 0,
let totalEntries = collection.totalEntries,
let objects = self.ratings?.count where objects < totalEntries {
self.ratingsCollection = nil
collection.nextPage().onSuccess { (value) in
if let collection = value as? Collection<Rating> {
self.ratingsCollection = collection
} else {
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}.onFailure { error in
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}
}
Here are the errors themselves:
1. While type-checking 'loadMoreContent' at (path redacted).swift:46:3
2. While type-checking expression at [(path redacted).swift:54:9 - line:64:9]
RangeText="collection.nextPage().onSuccess { (value) in
if let collection = value as? Collection<Rating> {
self.ratingsCollection = collection
} else {
self.ratingsCollection = Collection<Rating>(identifier: 0)
}
}.onFailure { error in
self.ratingsCollection = Collection<Rating>(identifier: 0)
}"
3. While loading members for declaration 0x7fdda42ea2b0 at <invalid loc>
4. While deserializing 'producer' (FuncDecl #340)
Does anyone have any idea what can be wrong with this function at first glance? I should add it compiles with no changes in Xcode 6 / Swift 1.2.
This is a hair pulling error especially common in XCode7.
Occasionally the usual XCode stupid bug protocol (clean, XCode Restart, clean, build) fixes it. However, often it is due to one or more offending lines of code. This doesn't necessarily mean there is a bug in the code, either!
So, before restarting, it is sometimes useful to undo recent changes sequentially and trying to build as you go along. If any of your dependencies or frameworks have been updated since your last successful build, these could be a likely candidate.
There are a couple things that seem to produce this error fairly regularly. So please add to this list concisely if you can isolate specific issues that CONSISTENTLY cause errors for you:
1) String concatenation using the plus operator in calls to methods that use autoclosures (found in calls to XCGLogger):
public func myFunc(#autoclosure closure: () -> String?){
// do something
}
someInstance.myFunc("Hi " + nameStr + "!")
2) failure to call super.init() from subclass especially when super class is using a default initializer (you haven't explicitly created your own init)
3) Accidentally using a single equals sign to test for equality (using = instead of == ) especially in complex statement such as in this answer.