How to Check for 'Nil' in While Loop Condition in Swift

How to check for `nil` in while loop condition in Swift?

Your code cannot compile. nil can only appear in optionals.
You need to declare view with optional, var view: UIView? = self.superview.
Then compare it with nil in the while-loop.

var count: UInt = 0
var view: UIView? = self.superview
while view != nil { // Cannot invoke '!=' with an argument list of type '(@lvalue UIView, NilLiteralConvertible)'
count++
view = view!.superview
}

Or do a let binding, But it seems not necessary here, I think.

Swift optional value Unwrap in while loop condition

I strongly assume that error actually occurs on the cur = cur.next line, because cur is an optional. The "quick and dirty" fix would be
to unwrap it forcefully:

var cur: ListNode? = head
while cur != nil {
// do something with `cur!` ...

cur = cur!.next
}

But the proper solution is to use optional binding, which works not
only in combination with if but also with while:

var cur: ListNode? = head
while let node = cur {
// do something with `node` ...

cur = node.next
}

What's the most idiomatic way to do a while == nil in swift?

The Swift compiler may well be smart enough (when optimizing a release build) to recognize that inputTuple cannot be nil in your last statement.

But if you want to eliminate it anyway, you can wrap the loop in a function that returns a non-optional tuple. You can even use an inline closure, like this:

let (row, col): (Int, Int) = {
while true {
if let inputTuple = readPositionsFromUser() { return inputTuple }
print("\nPay attention!\n")
sleep(1)
}
}()

print("row=\(row) col=\(col)")

while loop that checks it's condition every second in swift

Using while loop like this will create an infinite loop actually. You should use Timer().

timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.loop), userInfo: nil, repeats: true)

And then

@objc
func loop() {
if yourCondition {
// your code here
timer.invalidate()
}
}

Make sure you declare timer with your other variable declarations, so it can be invalidated once your condition has been met:

var timer: Timer!

Swift optional binding in while loop

It's the same

while let someValue = someOptional
{
doSomethingThatmightAffectSomeOptional(with: someValue)
}

Here is a concrete example of iterating a linked list.

class ListNode
{
var value: String
var next: ListNode?

init(_ value: String, _ tail: ListNode?)
{
self.value = value
self.next = tail
}
}

let list = ListNode("foo", ListNode("bar", nil))

var currentNode: ListNode? = list
while let thisNode = currentNode
{
print(thisNode.value)
currentNode = thisNode.next
}

// prints foo and then bar and then stops

Why can't I use single equals(=) as part of my while loop condition?

The reason for the error with

while (responder = responder.next!) {

is that the only thing permitted after the keyword while is a condition, and the only thing that a condition can be is an expression that evaluates to a Bool. An assignment cannot be a Bool.


What you're trying to do is perfectly reasonable; I do it all the time. Here's my formulation:

    var r : UIResponder! = view
repeat { r = r.next } while !(r is UIViewController)
let vc = r as! UIViewController

You'll notice I don't check for nil at all in that formulation; if we reach the end of the responder chain without finding a view controller, something is very wrong and I want to crash.

Another formulation I use just walks the whole chain and prints it; in that one, I do check for nil, obviously:

    var r : UIResponder! = someResponder
repeat { print(r as Any, "\n"); r = r.next } while r != nil

How to check object is nil or not in swift?

If abc is an optional, then the usual way to do this would be to attempt to unwrap it in an if statement:

if let variableName = abc { // If casting, use, eg, if let var = abc as? NSString
// variableName will be abc, unwrapped
} else {
// abc is nil
}

However, to answer your actual question, your problem is that you're typing the variable such that it can never be optional.

Remember that in Swift, nil is a value which can only apply to optionals.

Since you've declared your variable as:

var abc: NSString ...

it is not optional, and cannot be nil.

Try declaring it as:

var abc: NSString? ...

or alternatively letting the compiler infer the type.

While with assignment in swift

You can use while case with a binding pattern plus a boolean condition:

// Swift 3 (Xcode 8):
while case let size = inputdata.readWithByteArray(&buf), size != -1 {
// process data

}

// Swift 2 (Xcode 7.3.1):
while case let size = inputdata.readWithByteArray(&buf) where size != -1 {
// process data

}

(Previous answers:) A straight-forward implementation would look like this:

var size = inputdata.readWithByteArray(&buf)
while size != -1 {
// process data ...

size = inputdata.readWithByteArray(&buf)
}

If the code-duplication bothers you then you can write it also as
(Swift 3/Xcode 8 only):

var size: Int
while (size = inputdata.readWithByteArray(&buf), size).1 != -1 {
// process data

}

Here the (...).1 expression evaluates to the second tuple element,
i.e. to size, and the first tuple element is only evaluated for
its side-effect. (This is possible in Swift because expressions
are evaluated from left to right, as stated by Chris Lattner
in https://forums.developer.apple.com/thread/20001#63783.)

Swift - While Loops not functioning

The problem is that you are redeclaring next inside the body of your loop:

var next = last + lastLast

should be

next = last + lastLast

Once you make this correction, your code runs fine, producing the result below:

[0, 1, 1, 2, 3, 5, 8, 13]
13

Demo.



Related Topics



Leave a reply



Submit