iPhone : Difference between nil vs Nil and true vs TRUE - iphone

What is difference between nil and Nil in iOS development?
And similarly what is difference between true and TRUE in iOS development?

I think this will help you understand the difference between nil and Nil.
Please find the below link:
Refer the answer of Damien_The_Unbeliever which states:
Googling "Nil vs nil" found this post http://numbergrinder.com/node/49, which states:
All three of these values represent null, or zero pointer, values. The
difference is that while NULL represents zero for any pointer, nil is
specific to objects (e.g., id) and Nil is specific to class pointers.
It should be considered a best practice of sorts to use the right null
object in the right circumstance for documentation purposes, even
though there is nothing stopping someone from mixing and matching as
they go along.
Link for that answer can be seen here:
What does 'Nil' represent in Obj-C?
EDIT-2:
Is there a difference between YES/NO,TRUE/FALSE and true/false in objective-c?

nil is the literal null value for Objective-C objects, corresponding to the abstract type id or any Objective-C type declared via #interface. For instance:
NSString *someString = nil;
NSURL *someURL = nil;
id someObject = nil;
if (anotherObject == nil) // do something
Nil is the literal null value for Objective-C classes, corresponding to the type Class. Since most code doesn’t need variables to reference classes, its use is not common. One example is:
Class someClass = Nil;
Class anotherClass = [NSString class];

Related

How to convert Swift optional into Objective-C

I have read up on Swift optionals, specifically if let, but cannot make sense of this code. The tutorial is a swift project, but I am trying to use it to update an old Obj-C project. I am not trying to create an if let optional in objective-c, but rather just figure out how to make an Obj-C version do what he is doing here with Swift. The underlying code doesn't return a value.
if let user = user << Obj alternative
Following a tutorial and here is the code:
[[FIRAuth auth] signInWithEmail:userEmail
password:userPass
completion:^(FIRUser * _Nullable user, NSError * _Nullable error) {
if(error == nil) { // No ERROR so already so user already in Firebase
if let user = user{
NSDictionary *userData = #{ #"provider": user.providerID};
[[DataService instance] createFirebaseDBUserWithUid:user.uid
userData:userData
isDriver:NO];
}
DLog(#"Email user Auth successfully in Firebase");
Here is the createFirebaseDBUserWithUid:user code (possible returns a Firebase id value)
#objc func createFirebaseDBUser(uid: String, userData: Dictionary<String, Any>, isDriver: Bool) {
if isDriver {
REF_DRIVERS.child(uid).updateChildValues(userData)
} else {
REF_USERS.child(uid).updateChildValues(userData)
}
}
Would an obj-c version just be:
if( user != nil ){
NSDictionary *userData = #{ #"provider": user.providerID};
[[DataService instance] createFirebaseDBUserWithUid:user.uid userData:userData isDriver:NO];
}
The trick with Objective-C of course is its behaviour if you send any message to anil reference.
At the time of its invention (1986) it was actually progress to have any method sent to a nil reference (which is 'faulty' in an if statement since it is 0 (the number) at the same time) simply returning nil (or 0 if you interpret it as a number) and again 'faulty'.
In this sense you are 'mostly' correct if you do
if (user != nil)
in Objective-C wherever you see
if let user = user {
...
}
in Swift. Technically speaking it is not entirely the same, since the let-expression will give you a non-nullable reference to the same content shadowing the optional object for the following scope. So you do not have to do any more unwrapping of the user object in the scope of the if. Note however, that the user will again be optional after the if statement. This is adequately covered by the nil check in the Objective-C counterpart.
There may be "unusual" edge cases you could miss if the author of the Objective-C code relied on the "strange" interpretation of method passing in Objective-C. Nowadays it is considered bad practice to rely on these, but there used to be a time when we had chains of method calls that relied on said behaviour. Swift was invented partly to get rid of those sometimes unintended effects in method chains.
Objective-C Type is equivalent to Type! in Swift. for example: Objective-C NSDictionary would be NSDictionary! in Swift
Thus, Objective-C types are optionals by default and reading a Swift Type in Objective-C won't be affected by being an optional or not.
back to your question, as the intention of the code is not clear for me, generally, the code you wrote will generate a dictionary that contains one pair of (key, value) with the providerID which is not related to being optional or not.
the issue that you would face is if the User object was created in Swift, and you want to read it in Objective-C, then you have set it up for that

Is there a correct way to determine that an NSNumber is derived from a Bool using Swift?

An NSNumber containing a Bool is easily confused with other types that can be wrapped in the NSNumber class:
NSNumber(bool:true).boolValue // true
NSNumber(integer: 1).boolValue // true
NSNumber(integer: 1) as? Bool // true
NSNumber(bool:true) as? Int // 1
NSNumber(bool:true).isEqualToNumber(1) // true
NSNumber(integer: 1).isEqualToNumber(true) // true
However, information about its original type is retained, as we can see here:
NSNumber(bool:true).objCType.memory == 99 // true
NSNumber(bool:true).dynamicType.className() == "__NSCFBoolean" // true
NSNumber(bool:true).isEqualToValue(true) || NSNumber(bool:true).isEqualToValue(false) //true
The question is: which of these approaches is the best (and/or safest) approach to determining when a Bool has been wrapped within an NSNumber rather than something else? Are all equally valid? Or, is there another, better solution?
You can ask the same question for Objective-C, and here is an answer in Objective-C - which you can call from, or translate into, Swift.
NSNumber is toll-free bridged to CFNumberRef, which is another way of saying an NSNumber object is in fact a CFNumber one (and vice-versa). Now CFNumberRef has a specific type for booleans, CFBooleanRef, and this is used when creating a boolean CFNumberRef aka NSNumber *... So all you need to do is check whether your NSNumber * is an instance of CFBooleanRef:
- (BOOL) isBoolNumber:(NSNumber *)num
{
CFTypeID boolID = CFBooleanGetTypeID(); // the type ID of CFBoolean
CFTypeID numID = CFGetTypeID((__bridge CFTypeRef)(num)); // the type ID of num
return numID == boolID;
}
Note: You may notice that NSNumber/CFNumber objects created from booleans are actually pre-defined constant objects; one for YES, one for NO. You may be tempted to rely on this for identification. However, though is currently appears to be true, and is shown in Apple's source code, to our knowledge it is not documented so should not be relied upon.
HTH
Addendum
Swift code translation (by GoodbyeStackOverflow):
func isBoolNumber(num:NSNumber) -> Bool
{
let boolID = CFBooleanGetTypeID() // the type ID of CFBoolean
let numID = CFGetTypeID(num) // the type ID of num
return numID == boolID
}
The first one is the correct one.
NSNumber is an Objective-C class. It is built for Objective-C. It stores the type using the type encodings of Objective-C. So in Objctive-C the best solution would be:
number.objCType[0] == #encoding(BOOL)[0] // or string compare, what is not necessary here
This ensures that a change of the type encoding will work after re-compile.
AFAIK you do not have #encoding() in Swift. So you have to use a literal. However, this will not break, because #encoding() is replaced at compile time and changing the encodings would break with compiled code. Unlikely.
The second approach uses a internal identifier. This is likely subject of change.
I think the third approach will have false positives.
Don't rely on the class name as it likely belongs to a class cluster, and it is an implementation detail (and therefore subject to change).
Unfortunately, the Objective-C BOOL type was originally a just typedef for a signed char in C, which is always encoded as c (this is the 99 value you are seeing, since c in ASCII is 99).
In modern Objective-C, I believe the BOOL type is an actual Boolean type (i.e. no longer just a typedef for signed char) but for compatibility, it still encodes as c when given to #encode().
So, there's no way to tell whether the 99 originally referred to a signed char or a BOOL, as far as NSNumber is concerned they are the same.
Maybe if you explain why you need to know whether the NSNumber was originally a BOOL, there may be a better solution.

How is Optional variables a "powerful solution"?

I was thinking how this "Powerful Solution" according to apple of the Optional Variables is actually powerful if it's something that we already had in Obj-c?
var mystring: String? = nil
if mystring {
//string is not nil
}
Second Scenario won't compile
var mystring: String = nil
if mystring {
//string is not nil
}
We were able to do this in Obj-C before without any additional set up.
NSString * somestring = #"Test";
if(something != [NSNull null]){
//Do something.
}
or
NSString * anotherstring = nil;
if(anotherstring == [NSNull null]){
//display error.
}
so I am really confused on how this is that powerful as they claim if it already existed in a former language.
Some info about Optional Variables
The optional is a type on its own (actually an enum), and it can hold 2 values:
an actual instance/value of the type the optional is used for (corresponding to the Some enum case)
a nil value (corresponding to the None enum case), which represent the absence of value
The difference with other languages like ObjectiveC is that optionals don't use a valid type value, which can have a meaning in some cases and a different meaning in others.
In objective C, the absence of a reference type is represented by nil, which is actually a pointer to the location 0x00000000 (in a 32 bits scenario).
The absence of a value type instead is usually by convention. A function returning an integer can define -1 as absence of value, but -1 is an integer itself, and if the function can return negative values it cannot be used.
In Swift instead an optional can have either a valid integer value, or None, which is not itself an integer (nor an instance of a class, a struct, or whatever type is used with the optional).
Also, more important, you cannot assign nil to a non optional variable - that results in a compilation error, hence preventing a lot of common bugs that usually are discovered at runtime, and frequently hard to track down.
Last, whereas in objective C you can use nil for reference types, you cannot use for value type (as mentioned above for the integer type). In swift instead an optional can be nil regardless of the contained type - so a Int? can be either an integer or nil.
Swift optionals let you make it explicit whether a variable can be nil, whereas Objective-C is all for guessing games. Less nightmares about EXC_BAD_ACCESS errors. That's where the power lies.
In Objective-C a pointer to an object could be nil, yes. But there was no enforcement about if nil made sense.
NSString *shouldNeverBeNil = #"a string!";
shouldNeverBeNil = nil;
NSLog("Hello, %#", shouldNeverBeNil); // "Hello, "
In ObjC this compiles fine though we should never say hello to nothing. That's a bug.
But if we do the same in Swift it doesn't even compile and we don't get a runtime bug at all.
var shouldNeverBeNil: String = "a string!"
shouldNeverBeNil = nil; // Compilation error.
NSLog("Hello, %#", shouldNeverBeNil); // never happens
Optionals allow you to bless variables with the ability to be nil. Compilation errors are always preferable to runtime errors since it's impossible for an end user of your app to run into a compilation error.
If you want to allow that value to be nil Swift makes you bless it explicitly, as an Optional. Now if it's nil, you explicitly allowed it and Swift reminds you to handle handle both the nil case and the value case in your code.
var okToBeNil: String? = "a string!"
okToBeNil = nil;
if okToBeNil != nil {
NSLog("Hello, %#", okToBeNil!); // never happens
} else {
NSLog("What is your name?")
}

What is the intended use of optional variable/constant in swift

In objC,
NSString *stringValue = #"123s";
NSInteger *intValue = [stringValue integerValue];
NSLog(#"intergerValue %#",intValue);
if(!intValue)
{
NSLog(#"caught null object");
}
else
{
// Do appropriate operation with the not null object
}
prints " interValue (null) "
" caught null object "
and the binding is done safely by using !(not) operator inside if condition...
But whereas, in swift the equivalent snippet using optional variable is
var normalValue : String = "123s"
var optionalValue = normalValue.toInt()
println("optionvalue \(optionalValue)")
if optionalValue {
// Do appropriate operation with the not nil value
}
else{
println("caught null object")
}
this "optional binding" is done in objectiveC also, then what is the exact use of having optional variable/constant. And it's also been said that we can avoid returning null object instead we can return nil value. What is the problem when we return a null object, does it cause performance issues?
Your valid thoughts....
The intention behind optional types was to let programmers make variables that might not have a value. It was the default model in Objective-C, it has been reversed in Swift, because the language requires variables to have a value by default.
Objective-C refers to all objects through pointers (hence the asterisk * after the type name). Since all pointers are allowed to have no value (i.e. nil) one could think of all Objective-C objects as optional, i.e. the corresponding variable may have no value at all.
Since Swift does not have a requirement of C compatibility on the source code level, language designers choose to require objects to have a value of the specified type, and provided support for making variables that may not have a value through optional types.

Check if constant is defined at runtime in Obj-C

To, for example, access variables in a NSDictionary Cocoa frameworks often define keys, such as UIKeyboardBoundsUserInfoKey. How can I check if a key is defined at runtime? I found examples on how to check for classes and functions, but not for constants.
Jasarien's answer is roughly correct, but is prone to issues under LLVM 1.5 where the compiler will optimise the if-statement away.
You should also be comparing the address of the constant to NULL, rather than nil (nil has different semantics).
A more accurate solution is this:
BOOL isKeyboardBoundsKeyAvailable = (&UIKeyboardBoundsUserInfoKey != NULL);
if (isKeyboardBoundsKeyAvailable) {
// UIKeyboardBoundsUserInfoKey defined
}
Check it's pointer against nil, like this
if (&UIKeyboardBoundsUserInfoKey != nil)
{
//Key exists
}