What does `->` symbol represent in objective-c [duplicate] - objective-c

This question already has answers here:
What does this ' ->' mean in c/objective-c?
(7 answers)
What is the difference between '->' (arrow operator) and '.' (dot operator) in Objective-C?
(3 answers)
Dot (".") operator and arrow ("->") operator use in C vs. Objective-C
(5 answers)
Closed 10 years ago.
I have been looking at some code and come across the symbol -> being used like obj->method(argument); I have done a little bit of research and found it basically is the same as [obj method:argument]; but I am unsure what -> actually is or does.
So my question is, what does the -> symbol mean in objective-c?

It means the same as the struct dereference operator does in C, which is used to access fields within the struct via a pointer:
struct mystruct
{
int field;
};
struct mystruct *mystruct = ...;
printf("field=%d\n", mystruct->field);
In Objective-C it can also be used to access fields within Objective-C objects:
#interface MyObj : NSObject
{
#public
int field;
}
#end
MyObj *myObj = [[MyObj alloc] init];
NSLog(#"field=%d", myObj->field);
Note that you can only access these fields externally if they are declared #public.

I have been looking at some code and come across the symbol -> being
used like obj->method(argument); I have done a little bit of research
and found it basically is the same as [obj method:argument]; but I am
unsure what -> actually is or does.
So my question is, what does the -> symbol mean in objective-c?
Exactly the same thing it means in C; it is for accessing an item in a C structure. Way back in the days of yore, Objective-C was implemented purely as a C preprocessor extension + a runtime. Classes were nothing more than concatenated C structures and the preprocessor turned each ivar access into self->ivar.
I.e. ivar and self->ivar do the same thing (in a method of class).
Now, you can use -> to poke at some other object's (#public) ivars. But don't. That breaks encapsulation exactly because Objective-C's line of encapsulation is drawn at the method interface. Always use the setters/getters such that behavior can be either observed or overridden.
Finally, no, there is nothing like obj->method(argument) anymore. There was, once, in a failed experiment called Modern Syntax, but it was abandoned because it was a pointless waste of time. You can't use -> to invoke methods.

Related

How can I get sizeof class based on NSObject [duplicate]

This question already has answers here:
Checking the size of an object in Objective-C
(6 answers)
Closed 8 years ago.
I'm new to obj-c . During these day's practices I noticed that every class based on NSObject can't have an entity like : NSObject en; in c++ but NSObject* en instead.
But, sometimes I need to know the Size of an Object.I can't simply write sizeof(en) because en is a pointer var.I can't simply use sizeof(NSObject) neither for the compiler telling me Application of sizeof to interface 'XXXX' is not supported on this architecture and platform.
I want to know if there is a way to get sizeof(NSObject) .If not,what the syntax is designed this for & any other ways to get the size.
From doc
class_getInstanceSize
Returns the size of instances of a class.
size_t class_getInstanceSize(Class cls)
Parameters cls A class object.
Return Value The size in bytes of instances of the class cls, or 0 if
cls is Nil.
But I doubt this is what you really want. Because I never found it useful and can't think a case it may be useful. (other than learning memory layout of objects and low level implementation details)
First, you should import malloc.h
If you use Non-ARC:
malloc_size(myObject);
if you are using ARC:
malloc_size((__bridge const void *) myObject));
This linker is a question similar to yours.

Box Custom Struct in Objective-C [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to wrap a Struct into NSObject
Can the new Clang Objective-C literals be redirected to custom classes?
I have a custom struct:
typedef struct {
float f1;
float f2;
} MYCustomStruct;
that I need to add to an NSArray. I've already written a category to create NSValues of these structs, which I then add to the NSArray, however I'd like to simplify that even further using boxed expressions, if possible. I'd love to be able to do this:
#[#(instanceOfMYCustomStruct)];
however, I'm confronted with the following error:
Illegal type 'MYCustomStruct' used in a boxed expression
Is there a way to use boxed expressions with custom structs?
I would use a NSValue to box a struct, as it has built-in support for it. Unfortunately, you cannot use objective-c's cool literals for it, though:
struct foo myStruct;
NSValue *val = [NSValue valueWithBytes:&myStruct objCType:#encode(typeof(myStruct))];
// to pull it out...
struct foo myStruct;
[val getValue:&myStruct];
While this may be unwieldy & ugly amidst other objc code, you have to ask yourself - why are you using a struct in the first place in Objective-C? There are few speed performances gained over using an object with a few #property(s), the only real reason I could see is if you are integrating with a C library for compatibility with memory layouts, and even then, the structure of an objective-c object's memory layout is well-defined, so long as the superclass doesn't change.
So what is your real purpose in boxing a struct? If we have that, we can help you further.

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)

Dot (".") operator and arrow ("->") operator use in C vs. 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.

What is "->" in Objective C?

I've seen this operator pop up quite a few times in example code in "Learn Objective C on the Mac."
I believe it's an operator in the C language which Objective C inherits.
I tried Googling and searching Stack Overflow and oddly nothing came up.
Does it have an English name?
It has to do with structures.
When we have a struct available locally on the stack, we access its members with the . operator. For example:
CGPoint p = CGPointMake(42,42);
NSLog(#"%f", p.x);
However, if we instead have a pointer to a structure, we have to use the -> operator:
CGPoint *p = malloc(1*sizeof(CGPoint));
p->x = 42.0f;
NSLog(#"%f", p->x);
free(p);
-> is not specific to Objective-C. It's a C operator.
Now that's cleared, it's the member access operator, equivalent to a pointer dereference and then using the dot operator on the result.
Say you had a struct like this:
typedef struct Person {
char *name;
} Person;
Person *jacob = malloc(1*sizeof(Person));
So this statement:
jacob->name = "Jacob";
Is equivalent to this statement:
(*jacob).name = "Jacob";
Of course, don't forget the free:
free(jacob);
In C
a->b
is a shortcut for
(*a).b
which is for dereferencing of members of a struct that is pointed to.
This is useful, because of . binds stronger than the dereferencing operator * . So by using -> you avoid having to use these ugly parentheses.
It's a member selection (or access) equivalent to a pointer de-reference (as pointed out in comments)
a->member is equivalent to (*a).member in C/C++
The same thing that it means in C. It can be used to access the instance variables of objects directly, but generally this is not the best practice. The dot notation you're referring to is a property, not the usual C dot notation.
It's the "indirect member access operator". It's a C operator, which both Objective-C and C++ inherited.
This
a->b
is equivalent to:
(*a).b
but is less typing. (The parens are necessary in the expanded form due to precedence of * and ..)
a->b is equivalent to (*a).b, and designates member b of the object pointed to by a.
In the C standard, it is called the "structure/union pointer operator," which isn't really the catchiest name.
It's all been said, it is a shortcut for accessing members of a struct pointer, but just a note to add that you can access ivars using the same syntax due to the way the Objective-C runtime works:
#interface Foo : NSObject {
NSString *something;
}
/* ... SNIP ... */
NSLog(#"something = %#", foo->something); // Where foo is an instance of the Foo class
This is handy when you need to access ivars that aren't exposed by methods; specifically when you need to implement copyWithZone: on your objects.