Constant in viewDidLoad error - swift

I am trying to make a simple addition program, but when I put my let function in the viewDidLoad, it gives me this error:
initialization of immutable value 'doMath' was never used; consider
replacing with assignment to '_' or removing it.
Here is the code
let doMath: (Int!, Int!) -> Int =
mathFunction(text1, text2)
}
What should I do?

This is something new in swift2 that is if you are not using the particular variable then replace it with _ or use that variable, that's why it suggests you to replace your variable name with _. This is mainly designed for reducing memory and CPU usage.

It is not an error. It is a warning.
initialization of immutable value 'doMath' was never used; consider replacing with assignment to '_' or removing
What this means is that you never use doMath after declaring it. As soon as you actually use doMath in your code, the warning will go away.

Yes, as stated it is a warning letting you know that you have declared a variable that has not been used either before or after the declaration. The warning message suggests that you replace the variable (doMath) with a simple (_) as doMath is not used outside of the declaration.
Your options are to ignore the warning message, or to use it outside of the declaration.
You could also set up the function completely different if you are only looking for a simple addition function.
var firstNumber = 4
var secondNumber = 6
var doMath = (firstNumber + secondNumber)
print(doMath)

Related

How to get UnsafeRawPointer on the swift object?

My app uses the native C++ lib, there is a method that takes as an argument void*
void foo(void * obj) { ... }
in swift I can call this method like this
func boo(obj: MyCustomObj) {
foo(&obj)
}
and looks like really I get a void pointer on the object, but if I try to get an UnsafeRawPointer on the object like this
func boo(obj: MyCustomObj) {
var pointer = &obj <---- Use of extraneous '&'
foo(pointer)
}
I got an error
Use of extraneous '&'
What is the problem here?
EDIT
I understood that using withUnsafe*** I can get the pointer to the data, but what to do if my method has 2 params, would it looks like this
withUnsafePointer(to: myObjFirst) {
pFirst in
withUnsafePointer(to: myObjSecond) {
pSecond in
foo(pFirst, pSecond)
}
}
The & syntax does not mean "the address of" or "pointer to" like in C. In Swift, it is an in-out expression.
These can be used to create implicit pointer conversions as a convenience, and that can seem like C's "pointer to" meaning, but it has very different rules and behaviors. For example, there is no promise that obj even has an address. It may be a tagged pointer. Passing it via an in-out expression may allocate memory and copy the value to make the call possible. Similarly, when passing a "pointer to an array," Swift will actually pass a pointer to a contiguous block of values (which may have been copied to make them contiguous) which is not the same as the actual Array struct.
It is not meaningful to say var pointer = &obj. There is no in-out reference there.
There is no general way to take long-lived pointers to objects in Swift without allocating your own memory (and this is rare). The memory model doesn't promise the kinds of lifetimes you'd need to make that sensible. If your code did compile the way you expect it to, the call to foo(pointer) would still be invalid because there's no promise that obj exists at that point and the pointer could be dangling. (There are no references to obj after the first line, so Swift can and often will destroy it, even though it's still "in scope.")
The foo(&obj) syntax is basically a shorthand for:
withUnsafePointer(to: obj) { foo($0) }
It exists to make it easier to call C functions, but it doesn't mean that Swift pointers are anything like C pointers.
For much more on Swift pointers, see Safely manage pointers in Swift from WWDC 2020.

Immutable value never used in for in loop

I'm learning Swift and have started a Playground in Xcode 9.2. I've got the following code and whilst it is running as expected, it's giving me an warning message. What does it mean? I tried searching elsewhere but I can't find out why it's returning a warning.
for myCounter in 1...3 {
print("My counter")
}
The warning:
Immutable value 'myCounter' was never used; consider replacing with '_' or removing it
I tried doing what it said, and it seemed to work and not return any warnings, but why would that make a difference?
for _ in 1...3 {
print("My counter")
}
What's the difference here and why does it cause this?
The warning is telling that you are not using myCounter for anything, when you don't care about something in Swift you use _ to tell the compiler that your intention is to not use that value.
The warnings would also go away if you started using the value:
for myCounter in 1...3 {
print("My counter: \(myCounter)")
}
Swift has a smart compiler which optimizes. You are assigning 1, 2, and 3 into variable storage, to no purpose; you never use that variable for anything. So that is a waste of time and storage space. Therefore the compiler warns you to try to get you to improve the program. You did. It stopped warning.

Swift optional binding constant names

I am just transitioning from Objective-C to Swift and have been constantly writing the following code for optional binding,
if let tempX = X {
}
My question is I have to do it so often that I need to find a new name for constant every time. What's the way to avoid having a new name tempX for every optional X in the code? Wouldn't something like work?
if let X = X {
}
Yes, you can reuse the same identifier in such bindings. But keep in mind that the redefined, non-optionalX will only be visible inside the if scope.
But if you use a guard statement, the new X may shadow the previous variable (i.e., if previous variable was defined in another scope; otherwise will trigger a compiler error). Some would say this could hurt your code readability.
For further information, please see this related question.
The new constant is only defined within the scope of your if let, so as soon as the scope is over, your tempX is gone. That also means that you can reuse names within the if let scope.
if let X = X {
}

Swift let is mutable in classes why?

Hello everyone I am trying to figure out why the swift code below allows me to assign a new value to the wee string in my class. I thought let was immutable but it works here. Can someone please explain this. Thanks.
import Foundation
class MyClass {
let wee:String
init?(inInt:Int) {
let j:String = "what"
//j = "I shouldn't be able to do this wiht let" // error rightly so
//println(j)
self.wee = "wow"
if inInt != 2 {
return nil
}
self.wee = "hey"
self.wee = "blas" // I shouldn't be able to do this
}
}
if let myClass:MyClass = MyClass(inInt: 2) {
myClass.wee // prints blas
}
The "Modifying Constant Properties During Initialization" heading under the Initialization section of The Swift Programming Language says:
You can modify the value of a constant property at any point during
initialization, as long as it is set to a definite value by the time
initialization finishes.
Reading between the lines, and considering your example, it sounds very much like restrictions on setting the value of a constant don't apply to initialization. Further evidence supporting that idea appears earlier in the same section:
When you assign a default value to a stored property, or set its
initial value within an initializer, the value of that property is set
directly, without calling any property observers.
It's not unlikely that the constancy of a stored property is enforced by the accessors for that property. If those accessors aren't used during initialization, then it makes sense that you can modify even a constant property as many times as you like during initialization.
The fact that you can't modify j in your example after first setting it is due to the fact that j is a local constant, not a property. There probably aren't any accessors for j at all -- instead the compiler probably enforces access rules for local constants/variables.
Because you are assigning it in initialiser, at a point when object of that class is being created. I just assume, it take any last given value and then creates a constant.
If you would try the same in different function, it would not work. You would get an error.
It is not possible in swift 4.
Apple docs says:
You can assign a value to a constant property at any point during initialization, as long as it is set to a definite value by the time initialization finishes. Once a constant property is assigned a value, it can't be further modified.

Optional properties in swift

If I have property like:
var animatedImagesView:JSAnimatedImagesView?
And eventually it gets initialized at the proper time, do I need to just keep using ! to unwrap it ad nauseum when I want to do something to it? For instance:
self.animatedImagesView!.reloadData()
Usually I unwrap optionals like:
if let dailySleepTime:AnyObject = uw_JSON["daily_sleep_time"] {
self.settings.dailySleepTime = dailySleepTime as String
} else {
log.warning("\n Error finding attr in \(request)\n")
}
but I can't just go around casting my properties to constants in the same way right? I'm not complaining, I'm just wondering if I'm using the exclamation point correctly.
One option is to define animatedImageView as an implicitly unwrapped optional to begin with:
var animatedImagesView: JSAnimatedImagesView!
This is common when dealing with Cocoa .nib objects in Interface Builder, because the View can't be initialized until it is unarchived from the .nib, but you know that it will always be initialized before you use it.
I hate using the ! in general, because it is a runtime error just waiting to happen, but IB objects are one of the few places where its use seems both legitimate and necessary. Otherwise, your two other options are the ones that you have already found - unwrapping it every time using if let... (which is safest, but a pain in the a**), or using the ! every time that you use it, which isn't any safer than just declaring it using ! to begin with.
If you initialize it at the correct time (for example in any of the lifecycle methods, or in the constructor for that matter) you could just use ! instead of ? for the property declaration. I myself usually only use ? for stuff which I dont necessarily know will have a value at all times during my lifecycle.
If the latter is the case for you as well, you need to continue using ? since you can't guarantee you have a value stored. And you should also use the if let myVar = myVar { .. } syntax if you do multiple calls to the variable.
Instead, declare it as follows:
var animatedImagesView:JSAnimatedImagesView!
That implicitly unwrapped optional will obviate the need to constantly "bang" dereference it, but be sure it is never nil at any time accessed.
It's a great way to specify IBOutlets you know will always be initialized from the nib or storyboard before you use them.