Override truth or ! operator in Objective-C - objective-c

How do I override the truth-value of my class instance, or its ! operator?
For example (simplified names/usage):
MyClass variable = [MyClass alloc] initWithValue: nil];
...
if (!variable) { NSLog(#"'Not variable value' works"); }
I've searched for two possible solutions but couldn't find anything useful. In some languages i would overload an isTrue, asBool, etc function; or override the unary ! operator FOR THAT CLASS (not the main NOT operator.
My initial reaction to this problem was: You don't need to in Objective-C, you're going at it wrong. While true, I have lost over hours debugging some code that had the above (!variable) instead of
if (!variable.value) { NSLog(#"'Not variable value' works"); }
MyClass has property value among many others, which you can set or not. It defines whether or not you do something so it is common to need if (!variable.value){ NSLog(#"Warning, value not set"); }
So I want to overload the ! or isTrue function to check whether or not variable.value is set instead of merely checking if variable is linked to an address. This would make my code more readable and make my class more useable.
To be clear, in this example, variable points to an alloc-init'ed object, where variable.value = nil for example.
For example this can be done in python by overloading __ nonzero __.
As a side question that would answer this question: How does the truth value of an object work in Objective-C?

You can't override these things in ObjC. ObjC behaves just like C in this regard-- object references are pointers, either valid or nil-- a nil value evaluates to NO in a boolean expression and any non-nil value will appear as YES.
The canonical check for "is this thing an invalid pointer" is if (!thing) { ... }.
If you are always doing this:
if (!variable.value) ...
then perhaps variable is of type NSNumber or some object container for a primitive? It's hard to tell without context what pattern you're using and whether there's a better idiom for this.

An object in Objective-C has the same meaning in a boolean expression as a pointer in C, because it is a C pointer. If the pointer is NULL -- or nil for an object -- then it's false; otherwise it's true.
You can't override operators in Objective-C.
This said, !variable.value does indeed test whether value is nil (assuming that value has an object type) -- the dot operator resolves to a message send [variable value] whose return value is then negated.

Related

What does Objective-C property get resolved to in runtime?

What does Objective-C property get resolved to in runtime? Will calling [obj valueForKey:#"property"] always yield the same result?
e.g.
obj.property
First, note that obj.property is precisely the same as [obj property]. Dot syntax is just syntactic sugar. While there are some small run-time implementation details related to properties that are different than other methods, for the purposes of this discussion, think only in terms of "I have an ivar named _key and a method called -key." The fact that you created that ivar and method by declaring a property is irrelevant for valueForKey:.
valueForKey: is a method, and it can be overridden by a class to return whatever it likes. The default behavior is that valueForKey: will first look for a method whose name matches the key, and will return the result of that. In the vast majority of cases, this means that if you have a property, then valueForKey:#"property" will return the value of it.
The full search path for the default implementation of valueForKey: is explained in "Accessor Search Implementation Details", but here is the "short" version:
get<Key>, <key>, is<Key> (yes, the first place it looks is getKey, which is a little embarrassing because you should not prefix getters with get unless they return values by reference, but there you go; it is the first thing checked.)
countOf<Key>, objectIn<Key>AtIndex:, and <key>AtIndexes. If a legal combination of these are found, then an NSArray-like proxy object is returned.
countOf<Key>, enumeratorOf<Key>, and memberOf<Key>:. If all three are found, then an NSSet-like proxy object is returned.
If accessInstanceVariablesDirectly is YES (the default), then ivars are checked, named _<key>, _is<Key>, <key>, or is<Key>. Yes, this is a way to access an object's private ivars.
If everything else failed, then it calls valueForUndefinedKey:, which is free to return a result (and this is in fact a very useful thing to do if you want a generic key/value store).
But nine times out of ten, you're going to get the value of the method named <key>.
Side note: valueForKey: returns an object. If the return is a number-like scalar (including BOOL), it will return an NSNumber. Otherwise it will return an NSValue. There is some special handling for NSPoint, NSRange, NSRect, and NSSize (on Mac; on iOS, only NSRange is handled specially I believe).
obj.property is the same as [obj property], not [obj valueForKey:#"property"];. The latter is part of a system called Key Value Coding that's separate from properties.

What is the -> operator doing in -copyWithZone:? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arrow operator (->) usage in C
Dot (“.”) operator and arrow (“->”) operator use in C vs. Objective-C
I'm a newbie looking at a freeware/open-source program last updated in 2008, and I don't recognize the -> in the following notation:
- (id)copyWithZone:(NSZone *)zone
{
GFIPGeniusItem * newItem = [[[self class] allocWithZone:zone] init];
newItem->_stringValue = [_stringValue copy];
newItem->_imageURL = [_imageURL copy];
newItem->_webResourceURL = [_webResourceURL copy];
newItem->_speakableStringValue = [_speakableStringValue copy];
newItem->_soundURL = [_soundURL copy];
return newItem;
}
I'm assuming it's allowing some sort of shortcut, but I'd love to specifically what it does.
It's a way to directly access an instance variable within an ObjC object from outside that object. (The syntax and -> is borrowed from C structs, behaving as if the reference were a pointer-to-structure).
This access mechanism is almost vestigial at this point, and very uncommonly seen in modern ObjC code, because good encapsulation requires the use of accessors and properties, not touching instance variables directly. It's legitimate in some very special cases, though, and this is one of them:
When copying an object, you want to get a resulting copy that matches exactly the state of the current self. The cleanest way of achieving this is often to set the copy's ivars explicitly, to prevent any side-effects that the init overloads or accessors might cause. It's "safe" because the code doing it is still located within the class that's in question, so if you needed to change or add ivars, you could update this code as well with the knowledge of anything else that might require.
Doing this from outside the class in question is bad form, and there's no good reason to do it.
In Objective-C you have some kind of two variable type accessors. The one everybody should know is the "." one (e.g. Class.variable). This type calls either the appropriate getter or setter.
Now, the other type - the one you asked for - is for in-class usage. Obviously, as the getter or setter gets called automatically with the "." notation you need a way to set the variable without a setter (calling the setter in the setter itself results in an endless loop). Therefore, this "->" notation is used -> simply, it is the direct-access mode.
Usually, Objective-C the variable name for both notations is the same but some prefer to have the in-class notation variable name beginning with "_". This is achieved by editing the #synthesize variable line to #synthesize variable = _variable.
That's a pointer indirection operator. a->b means the same thing as (*a).b (where the . is the structure member access operator, not Objective-C's property dot syntax).
When you say:
newItem->_stringValue
you're directly accessing the _stringValue instance variable of the object to which newItem points.
The -> operator is very common in C++, but not so much in Objective-C.
In Objective C, like in C++, the p->m notation is equivalent to (*p).m This is, the dereference of the pointer to the base type followed by a call to the corresponding method or property.
So in your case, using the other notation it would look like this:
(*newItem)._stringValue = [_stringValue copy];
(It's more common to use the -> operator)

Why do functions use -(void) and not -(nil) in Obj-C?

In objective-C I often see functions that don't return anything declared as:
- (void)myFunction {…
But why aren't functions declared using nil, like this
- (nil)myFunction {…
Don't they both return "nothing"?
void is nothing. nil is something (0).
In other words, returning nil isn't the same as returning nothing.
Historically in languages belonging (syntactically) to the C-like language family, void indicates that there is no type being returned from a function.
More precisely, just as variables have (or belong to) a given type, functions also have types. For example, a function that returns a int, it is an int type function, or a function whose type is int. Same if it returns something else.
If the function does not return anything - it returns nothing - what type does it belongs to? It has no type, and the void type represents such a thing.
I'm not versed in Objective C, but if I understand correctly, nil is an typeless ID (or an id of any type), almost like a built-in implementation of the null pattern.
And null is a (void *) type, the later being a typeless pointer that can point to anything, just as it would in C and C++.
So a function that returns nil would imply that its type is an id of any type. Don't know if that even makes sense. So right then and there, (nil)myFunction is of a type completely different from (void)myFunction since the former has one type (any type?) whereas the later has no type at all.
Also, nil is a built-in constant. Returning nill is like saying that your function returns a specific number for instance ((1)myFunction). That wouldn't make any sense, would it?
Void is an object type. Void means there is no return value.
Nil is an object, not a type. It represents an empty value.

What describes nil best? What's that really?

Currently I understand it as a kind of "empty object". But what's it really?
Objective-C objects
First of all, when you call this:
id someObject = [NSArray array];
someObject isn't the array object directly but only a pointer to it. That means, if someObject is equal to 0x1234 there's an object at that address in the memory.
That's the reason why
id someOtherObject = someObject;
doesn't copy the object. Both pointers point now to the same object.
Pointer to 0x0
So, how is nil defined? Let's take a look at the source code:
objc.h
#define nil __DARWIN_NULL /* id of Nil instance */
_types.h
#ifdef __cplusplus
…
#else /* ! __cplusplus */
#define __DARWIN_NULL ((void *)0)
#endif /* __cplusplus */
Looks like nil is a pointer to the address 0x0.
So what?
Let's see what the Objective-C Programming Reference has to say:
Sending Messages to nil
In Objective-C, it is valid to send a
message to nil—it simply has no effect
at runtime. There are several patterns
in Cocoa that take advantage of this
fact. The value returned from a
message to nil may also be valid: …
The returned values are either nil, 0 or a struct with all variables initialized to 0. Which one it is depends on the expected return type. There is an explicit check in the objective-c runtime for messages to nil, that means it's really fast.
Nil, nil, NULL
Those are the 3 types. Here are all the definitions:
#define Nil __DARWIN_NULL /* id of Nil class */
#define nil __DARWIN_NULL /* id of Nil instance */
#define NULL __DARWIN_NULL
#define __DARWIN_NULL ((void *)0)
As can be seen, they are all exactly the same. Nil and nil are defined by Objective-C, NULL comes from C.
What's the difference then? It's only about style. It makes the code more readable.
Nil is used as a non-existent class: Class someClass = Nil.
nil is used as a non-existent instance: id someInstance = nil.
NULL is a pointer to a non-existent memory part: char *theString = NULL.
Short
nil isn't an empty object but a non-existent one. A method -getSomeObject doesn't return an empty object if it doesn't exist but returns nil which tells the user that there is no object.
Maybe this makes sense: (Both would compile and run.)
if (anObject == nil) { // One cannot compare nothing to nothing,
// that wouldn't make sense.
if (anObject) { // Correct, one checks for the existence of anObject
It's not an empty object, it's the lack of any object at all. The rest of the answers cover the other semantics, so I'll leave it at that :)
nil should only be used with pointers, and nil represents a pointer which points to nothing (it's value is zero)
NSString *myString = nil; // myString points to nothing
int x = nil; // invalid, "x" is not a pointer, but it will compile
It's "nothing". But a "nothing" you can send messages to without getting killed as you would if you were trying to call a method on NULL.
You can look at this question to have more info on NULL vs. nil
It's a null pointer - a pointer to "nothing".
Formally defined, it is as Joshual defined - a pointer to nothing or a pointer to no object at all.
From a practical, implementation perspective, particularly when dealing with data structures and algorithms, a nill often will represent a sentinel in a data structure or an object that represents "nothing" for example, in a red-black tree, technically, all of the leaf nodes are "nill", but they still have the same or similar properties & operations of a leaf node (color, pointer to a parent, etc.) - in those cases, it is really a "nothing object" ... if that makes any sense.
So, formally, it is a pointer to nothing, in practice, it is often treated as a representation of nothing, but it is never ... null.
One useful way of thinking about nil is imagining that it's the empty object that "does nothing".
By "does nothing" I mean, any message you send it won't have side effects.
It's "empty" in the sense that when you ask it for the value of any property, it always returns nil. So it's not holding any values --> it's empty.
(Actually, it's a little more complicated than that, when you ask for the value of a property that returns a type that's NOT an obj-c object. You will get back a pointer-sized 0. So for any scalar values that are no larger than sizeof(void*) you get 0. But if you ask for a struct or a double on a 32 bit system, you get an undefined result. I've written about this here.)
Maybe I'm just missing the obvious but this seems like a semantic question. As in, you can use lots of different words to describe it, but your description works well enough already.
http://en.wikipedia.org/wiki/Null_(computer_programming)
Just to clarify, in Objective-C nil and null are not the same thing. Neither do they represent the same thing in Objective-C as they do in mathematics or other programming languages.
Nil is actually a special memory address of 0x0 (at least the compiler treats it as an address.) Nil is used as the address of an object that is named but not allocated. This allows for test for the existence/allocation of named objects as well as providing a safe way to send messages to objects that might not exist. While in math and some languages you can compare scalar variables to nil, in Objective-c, you should not. You should only compare the address of objects.
NULL by contrast can mean either the standard C defined as an integer value ofNULL==0 or it can represents an actual allocated object of the class NSNull with a specific address in memory. NSNull is however, a singleton object i.e. only one exist for every application. It is used as placeholder for other objects usually in collections. You cannot use it in comparisons with any other object. You can only check if a particular pointer points to the singleton NSNull object. Note however that as an allocated object[NSNull null]!=NULL,
The confusion between nil and NULL arises because assigning an address of NULL assigns it to the nil address of 0x0. Such code works but can cause subtle problem at times. It's best to get in the habit of not confusing the two.
So, in Objective-C, nil, NUll and NSNull are three different but overlapping concepts that are easy to confuse. Nil should be used for addresses, NULL should be used for scalar values and NSNull should be used as a placeholder for allocated objects.

What does the Asterisk * mean in Objective-C?

Is it true, that the Asterisk always means "Hey, that is a pointer!"
And an Pointer always holds an memory adress?
(Yes I know for the exception that a * is used for math operation)
For Example:
NSString* myString;
or
SomeClass* thatClass;
or
(*somePointerToAStruct).myStructComponent = 5;
I feel that there is more I need to know about the Asterirsk (*) than that I use it when defining an Variable that is a pointer to a class.
Because sometimes I already say in the declaration of an parameter that the Parameter variable is a pointer, and still I have to use the Asterisk in front of the Variable in order to access the value. That recently happened after I wanted to pass a pointer of an struct to a method in a way like [myObj myMethod:&myStruct], I could not access a component value from that structure even though my method declaration already said that there is a parameter (DemoStruct*)myVar which indeed should be already known as a pointer to that demostruct, still I had always to say: "Man, compiler. Listen! It IIISSS a pointer:" and write: (*myVar).myStructComponentX = 5;
I really really really do not understand why I have to say that twice. And only in this case.
When I use the Asterisk in context of an NSString* myString then I can just access myString however I like, without telling the compiler each time that it's a pointer. i.e. like using *myString = #"yep".
It just makes no sense to me.
an * is actually an operator to de-reference a pointer. The only time it means "hey i'm a pointer" is during variable declaration.
Foo* foo // declare foo, a pointer to a Foo object
&foo // the memory address of foo
*foo // de-reference the pointer - gives the Foo object (value)
mmattax well covered the distinction between declaration (as a pointer) and dereferencing.
However, as to your point about:
(*myVar).myStructComponentX = 5;
to access a member of an instance of a C struct (as this is) you can do what you did , or more commonly you use the -> notation:
myVar->myStructComponentX = 5;
Objective-C is a little confusing here because it recently (in ObjC 2.0) introduced property syntax, which is a short cut for:
int val = [myObject someIntProperty];
and can now be written as:
int val = myObject.someIntProperty;
This is Objective C (2.0) syntax for accessing a property which you have declared (not an actual member variable), whereas your example was accessing a member of a C struct.
Make sure you are clear on the difference.
As I said in my answer of your previous question, #"yep" is already a pointer, so there is no need of * before myString which is also a pointer. In this case, you assign pointers not values.