Dot (".") operator and arrow ("->") operator use in C vs. Objective-C - objective-c

I'm trying to wrap my head around some of the differences in usage and syntax in C vs. Objective-C. In particular, I want to know how (and why) the usage differs for the dot operator and the arrow operator in C vs. Objective-C. Here is a simple example.
C Code:
// declare a pointer to a Fraction
struct Fraction *frac;
...
// reference an 'instance' variable
int n = (*frac).numerator; // these two expressions
int n = frac->numerator; // are equivalent
Objective-C Code:
// declare a pointer to a Fraction
Fraction *frac = [[Fraction alloc] init];
...
// reference an instance variable
int n = frac.numerator; // why isn't this (*frac).numerator or frac->numerator??
So, seeing how frac is the same in both programs (i.e. it is a pointer to a Fraction object or struct), why are they using different syntax when accessing properties? In particular, in C, the numerator property is accessed with frac->numerator, but with Objective-C, it is accessed using the dot operator, with frac.numerator. Since frac is a pointer in both programs, why are these expressions different? Can anyone help clarify this for me?

frac is actually not the same in both programs.
A C Fraction is a struct, which is a base type with no overloaded operators and is only really able to be constructed and destructed by default. If you define functions or fields on the struct, the way to access those properties in C is with the dot (.) operator. Objective-C maintains this operator when you use structs. For convenience, you can perform a dereference-and-dot operation using the arrow (->) operator (the two equivalent expressions you mention). Objective-C also preserves this when accessing structs.
An Objective-C Fraction in your example, however, is probably (one would assume) a pointer of at least type id, which is simply a classname and pointer to the instance of that class under the hood. It's also very likely to be a subclass of NSObject or NSProxy. These Objective-C classes are special in that they have a whole layer of predefined operations on top of just a C struct (if you really want to dig into it then you can take a look at the Objective-C Runtime Reference). Also important to note, an Objective-C class is always a pointer.
One of the most basic operations is objc_msgSend. When we operate on these types of objects, the Objective-C compiler interprets a dot (.) operator or the square bracket syntax ([object method]) as an objc_msgSend method call. For more detailed info about what actually happens here, see this series of posts by Bill Bumgarner, an Apple engineer who oversees the development of the Obj-C runtime.
The arrow (->) operator is not really supposed to be used on Objective-C objects. Like I said, Objective-C class instances are a C struct with an extra layer of communication added, but that layer of communication is essentially bypassed when you use the arrow. For example, if you open up Xcode and type in [UIApplication sharedApplication]-> and then bring up the method completion list, you see this:
Here you can see a bunch of normal fields which we generally access with square bracket syntax (like [[UIApplication sharedApplication] delegate]). These particular items, however, are the C fields that store the values of their respective Objective-C properties.
So, you can roughly think of it like this:
Dot operator on a C object
(at run time) Return value of the field
Arrow operator on a C object (pointer)
Dereference pointer
Return value of the field
Dot operator/square brackets on an Objective-C object (pointer)
(at compile time) Replace with call to objc_msgSend
(at run time) Look up Obj-C class definition, throw exception if something went wrong
Dereference pointer
Return value of the field
Arrow operator on an Objective-C object (pointer)
(at run time) Dereference pointer
Return value of the field
Now I'm definitely oversimplifying here, but to summarise: the arrow operators appear to do basically the same thing in both cases, but the dot operator has an extra/different meaning in Objective-C.

Dot-notation is a design choice. Since we always deal with pointers to objc instances, I'd guess the designers wanted something familiar, which also would not break existing programs. It was introduced in ObjC 2 - just a few years ago. Before that, you always had to use brackets for messaging.
Dot notation makes a difference though - it is not direct access, but a message.
That is:
obj.property = val;
// is the same as:
[obj setProperty:val];
// and not:
obj->property = val;
val = obj.property;
// is the same as:
val = [obj property];
// and not:
val = obj->property;
You can still write obj->ivar to access a pointer to object's members (if visible).

In your first example, Fraction is a struct.
In your second example, Fraction is an Objective-C class (and in iOS would likely be a subclass of NSObject).
C++ does not allow overloading of operator .. Therefore without additional information you can deduce that the dot notation you're seeing is an additional language construct integrated into Objective-C, rather than a C/C++ defined or overloaded operator.
As it happens, the dot notation is simply a design feature the implementors chose as shorthand for property access, entirely equivalent to the square bracket getter:
myObjCVar.prop == [myObjCVar prop];

The dot operator on objects is a special syntax for accessing objects' properties. It calls the property's getter or setter behind the scenes. So, for example, [#"hello" length] and #"hello".length are equivalent*. For all other types, the dot is the same as the C dot, and the arrow is always the same.
* Note: The accessor method won't always be named the same as the property. If it's a declared property and the declaration designates a special getter or setter method, that one will be used instead.

The dot and arrow notation are equally the same in C as it is in Objective-C (strict superset of ). I think the fundamental difference that needs to be distinguished is the difference between a struct and an Objective-C object.
The dot notation used for objects in Objective-C are used for properties that was introduced in Objective-C 2.0. However, with structs, the -> and dot notation between Objective-C and C are the same.

Related

Why are Objective-C blocks not handled through pointers as are other Objective-C objects?

In code that uses blocks, you frequently see declarations such as:
typedef void(^Thunk)(void);
Thunk block1 = ^{NSLog(#"%d %p",i, &i);};
instead of
typedef void(^Thunk)(void);
Thunk *block1 = ^{NSLog(#"%d %p",i, &i);};
Blocks seem to be the only Objective-C object that is handled directly, instead of through a pointer. Why is this? Aren't they regular objects?
If you're wondering about the missing *: In your example you typedef'd the block which is hiding the syntax. You can do this with other objects as well:
typedef NSNumber *Number;
Number foo = #42;
When assigning a block to a variable that's actually assigning a pointer.
Blocks are a bit like C arrays: Block literals are structures created by the compiler. Block variables are pointers behind the scenes.
You're not handling a block “directly”. You're handling it indirectly.
The syntax void (^)(void) declares a pointer to a block. There is no syntax for type “block”; there is only syntax for type “pointer to a block”.
From the Language Specification for Blocks:
The abstract declarator,
int (^)(char, float)
describes a reference to a Block that, when invoked, takes two parameters, the first of type char and the second of type float, and returns a value of type int. The Block referenced is of opaque data that may reside in automatic (stack) memory, global memory, or heap memory.
The relevant bit is “describes a reference to a Block”.
The specification isn't entirely consistent, since (for example) it refers to a “variable with Block type” and “Block variable declarations“. But in fact a variable always holds a reference (pointer) to a block, and never holds a block directly as its value.
If you look at the block implementation, you will see that blocks are ObjC objects.
If you inspect a stack block (like in your example), you'll see something like this:
(lldb) po myBlock
<__NSStackBlock__: 0xbfffc940>
And you will notice in the public header _Block_copy() and _Block_release() take void* arguments.
The non-pointeryness is just syntactic sugar the compiler provides to shield you from the dirty bits of blocks.
Blocks are a C extension. You can use blocks in C (where the extension is supported).
Apple just happens to have implemented blocks using ObjC types.
Implementation details: Blocks are one of the few ObjC types which may be allocated on the stack using clang. Normally, this is not an option because almost every API expects that an objc_object is a heap allocation which supports reference counting.

Can someone explain . and -> in objective c?

Help me :( i dont know why?
#interface RootViewController : UITableViewController {
BOOL isSearchOn;
}
self->isSearchOn = NO; ( no error)
self.isSearchOn = NO; ( error)
Dot operator . is used to access property.
Arrow operator -> is used to acces instance variable.
So you use
self->isSearchOn = NO; // which is an instance not a property
You can also use this way by skipping self->
isSearchOn = NO;
-> is the traditional C operator to access a member of a structure referenced by a pointer. Since Objective-C objects are (usually) used as pointers and an Objective-C class is a structure, you can use -> to access its members, which (usually) correspond to instance variables.
or
When applied to pointer arrow operator is equivalent to applying dot operator to pointee (ptr->field is equivalent to (*ptr).field)
or
pSomething->someMember
is equivalent to
(*pSomething).someMember
. is used when you have a object and want to reference a attribute or a method, while you must use -> when holding the pointer only. instead of using -> you could aswell go for *. but I guess that you should in any case read about pointers in C.
There are essentially three operators here, two of which are inherited from C and the third which is from Objective-C.
In C, . and -> do the same thing—they retrieve a value from a struct—but - automatically dereferences a pointer to a struct, so the following two expressions are equivalent:
(*a).b
a->b
The second operator is simply syntactic sugar. Importantly, however, . doesn't make any sense when applied to a pointer—you have to use ->.
Objective-C allows the use of . with an object pointer (and only with a pointer, since all Objective-C objects are pointers) to reference a property value, a much higher level construct than the C operators provide.
Therefore, you may use . on objects to retrieve properties defined in the interface with #property, but you will need to use -> to retrieve ivars (instance variables) directly, which isSearchOn is in your example. However, it is usually better practice to expose variables using properties in Objective-C rather than refer to them directly using C's -> operator.

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)

What does -> mean?

I'm a relative newbie to Objective-C (only studied Arron Hillegras's book) and am confused by the following snippit of code I've found in one of Apple's code examples, in particular what does the -> mean?
-(id) initWithNumbers:(NSArray *)numbers
{
self = [super init];
if (self != nil)
{
self->_numbers = [numbers copy];
}
return self;
}
In the header file _numbers is declared as
NSNumber * _number;
( the underscore has some significance from what I recall reading somewhere but that too eludes me at the moment.
Thanks
Robin
-> is a normal C operator for accessing the members of a pointer to a struct; the . operator is for accessing members of a struct. Thus:
a->b
is translated to
(*a).b
Since Objective-C objects are pointers to structs underneath it all, this works for accessing instance variables.
You use -> when you want to access an ivar. Like C structures you will use a . or -> (in pointers to structs) in Objective-C objects you can use -> but is not necessary since you can access them directly.
Hence:
self->_numbers = [numbers copy];
and
_numbers = [numbers copy];
are the same
You want to use -> when you want to access that ivar explicitly.
Be aware that in Objective-C you can use . but only when its a property.
You can use -> regardless that.
It's usually called the 'arrow' operator. It allows you to access the instance variables of an object (or of a struct) using a reference or pointer to the instance. It's common syntax with C and C++.
I'm struggling to find a nice write up, but you might find this one informative.
As to the underscore - commonly they mean "private"; according to the Coding Guidelines for Cocoa - Naming Basics:
Avoid the use of the underscore
character as a prefix meaning private,
especially in methods. Apple reserves
the use of this convention. Use by
third parties could result in
name-space collisions; they might
unwittingly override an existing
private method with one of their own,
with disastrous consequences.
That indicates a reference to -in this case- an instance variable of an object. Self refers to the object itself, and by writing self->_numbers, you refer to the variable that is part of the class instead of a global variable named _numbers.
Are you sure this is not mentioned in your book?
It's an operator which roots from C Programming Language. And since Objective-C is compatible with C programming, you may see developers using traditional C-style programming.
"->" is used to access a elements of a pointer. And since the "objects" in Objective-C are just pointers (denoted by *), e.g. NSNumber *number; , you can use this notation to access their elements.
I never used this notation in Objective-C since the dot notation in Objective-C is accepted. If "self" has a synthesized property "number" then self.number should be the same as self->number (this is true ONLY in Objective-C.

method taking mutli arguments in dot notation

i am viewing this video on objective c. the guy show a method which takes multiple arguments and it looks like this
- (void) setTo: (int) n over: (int) d
{ .... }
to use it he shows:
[myFraction setTo: 100 over:200];
how would that bracket notation look in dot noation? andi dont understand what that over
means, would anyone know? thnx
The dot notation is a shorthand notation for property access only. The compiler translates it to the appropriate setter/getter method call. It is just syntactic sugar.
So given this property access using dot notation:
myFraction.numerator=100;
The compiler replaces it with the following equivalent code:
[myFraction setNumerator:100]
Now it should be clear why you cannot use dot notation for sending a normal message to an object. I can't even think of a way how that should even look like.
There is a lot of discussion concerning dot vs. bracket notation going on. One of the arguments against dot notation is the confusion it generates especially for beginners. Other languages do of course use methods for property accessors too, however they hide this fact more consistently than Objective-C.
You cannot pass multiple arguments with dot notations. A setter usable by dot-notation must have the prototype
-(void)setXxxx:(type)value;
However, you can create an auxiliary struct to group all arguments into one:
struct Fraction { int n, d; };
struct Fraction MakeFraction(int n, int d) {
struct Fraction r;
r.n = n;
r.d = d;
return r;
}
...
-(void)setValue:(struct Fraction)f { ... }
...
myFraction.value = MakeFraction(100, 200);
(and a "over" b means a / b.)
From the looks of it, this method is setting two instance variables/properties of the object the numerator (n) and the denominator (d). You cannot do this using dot notation unless you break it into two calls:
myFraction.numerator=100;
myFraction.denominator=200;
Note that dot notation is only for accessing instance variables/properties and not an alternative to message sending.
In Objective-C, we can name methods with arguments in the middle. So when he writes [myFraction setTo:100 over:200];, the over could mean... well, whatever he wants. It's part of the method name he chose. In this case, he was probably trying to make the method sound like English. ("Set this fraction to 100 over 200." We read fractions as "numerator over denominator" often in normal speech.)
Some methods, called "accessors", we write very frequently: these are methods of the form - (int)variable (called "getters"), and - (void)setVariable:(int)newValue (called "setters"). My examples here would assumedly return, or change, respectively, an instance variable called variable. Here's what the method implementations might look like:
- (int)variable
{
return variable;
}
- (void)setVariable:(int)newValue
{
variable = newValue;
}
It's common to have accessors like this for almost every instance variable your class has. At some point, someone got tired of writing [myInstance setVariable:20]; and such, and decided they'd rather it look like many other languages out there, myInstance.variable = 20;.
Therefore, Objective-C 2.0 added dot notation, which allows you to write...
myInstance.variable, which is exactly equivalent to [myInstance variable] in most circumstances (and does NOT access the instance variable variable directly!), and...
the special case myInstance.variable = 20;, which is exactly equivalent to [myInstance setVariable:20];. Again, note that this does not access variable directly, it sends a message to myInstance. So if we'd written some other code in setVariable, it would still be accessed if we used dot notation.
Dot notation is designed to be used for accessors. You could also theoretically use it for any method that returns a value and takes no arguments (myArray.count, for example). Using it for anything else (myInstance.doSomeAction) is extremely poor style. Don't do it. Therefore, as I'm sure you can guess by now, [myFraction setTo:100 over:200] has no dot notation equivalent, as it takes 2 arguments, and isn't an accessor.
[myFraction numerator]
Could be written as
myFraction.numerator
but you can also assign values such as
instance.property = value
But you cannot pass multiple arguments in dot notation.