How are objects passed and returned in Objective-C? - objective-c

In Java, I can easily pass data using (ObjectA)objB. How can I do the similar things in Objective C? Also, why the Objective C can't return an Object, but only can return the id only? I do -(MyObj)returnMyObject{ }, but the Xcode warning me that I can't use the MyObj, but I can return the id..... -(id) returnMyObject {}.

The underlying model of Java and Apple's Objective C objects is really the same both have all objects on the heap and are accessed via pointers.
The difference is in Java the pointers are hidden so (ObjectA)objB is a pointer to data of type ObjectA. In Objective C the pointer is explicit and you need to say (MyObj*)returnMyObject{ }
id is a pointer to an object (so is an exception in that the pointer is implicit like Java)

As Mark has already pointed out; all Objective-C objects require the * at the end; it's always NSString *aString, never NSString aString.
This applies to casts as well; so you would have to do (MyObj *)anObject. Note, however, that the cast doesn't actually do anything, it's merely there as a hint for the compiler.

Related

What happens at the compiler level when casting one Objective C object to another

I know that in C casting one variable to another type tells the compiler to act as if that variable is of that type and size in memory.
Example:
int* a = (char*)b;
Take the value of b (which is a 1 byte memory address) and store that in the 4 byte variable a. (Correct me if i'm wrong)
How does this work which casting an Objective-C object?
I also understand that each object is just a C struct holding a pointer to its class, instance variable list, etc.
If I have a class which is a subclass of UIView called MyView and I am passed a pointer to a UIView, maybe a method argument, and I do this:
-(id)setupThisViewForMe:(UIView*)aView {
MyView* newView = (MyView*)aView;
newView = [[MyView alloc]initWithFrame:CGRectMake(0.0f,0.0f,100.0f,100.0f)];
[newView takeOverTheWorldWithMyMethodInSubclass];
return newView;
}
What exactly is the compiler doing at compile time?
What exactly is the compiler doing at compile time [when you cast Objective C objects]?
Almost nothing: the compiler performs checks related to ARC, making sure that you are not coercing a weak pointer into a strong variable or vice versa, but other than that, the compiler trusts you to do the right thing. Of course if you "lie" to your compiler, it will "pay back" with unsupported message exceptions at runtime.

Why does an object variable have to be a pointer?

If I declare an NSMutableString
NSMutableString *str_value;
Why do I have to declare this as a pointer (using *)? If I don't, I get a compilation error.
Could someone explain this clearly?
Recall that Objective C is a superset of C. When you declare a variable without * in C, it is an indication that the memory for that variable is allocated either in the automatic storage if it is a local variable, as part of its outer structure if it is a member of a structure, or in the static memory if it is a static or a global. Using the typename or a structure tag without * in a parameter list of a function indicates passing by value.
The designers of the Objective C language could have taken the Java-like route, making every class instance is a pointer without the pointer syntax, but then the readers of programs in Objective C would need to know if a name represents a typedef based on a struct or an id type to answer even the most basic questions about objects of that type, such as if it is implicitly passed by pointer or by value, if it is allocated as part of the owning structure or as a heap object pointed to by a pointer inside the structure, and so on.
To avoid this kind of confusion, designers of Objective C decided to preserve the explicit pointer syntax for id objects.
A pointer means you are pointing / referencing to that class. Yes it will cause a compilation error, the reason for a pointer is mainly for memory. One data type (int or BOOL or float etc...) is only a few bytes, therefore it is not necessary to have a pointer. But NSMutableString and other Objective-C classes have a lot of properties and methods, with a lot of code. Therefore, since in your apps will have a lot of objects, which will use a lot of memory and thus slow down your app/decrease performance. Of course you should release the object once you make a pointer.

Why is it a pointer? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
objective c difference between id and void *
why most of the objects we create in iphone are pointers
According to Stanford university course, 2010/2011
Lecture 3
The guy made something strange there (at least for me), which is that
NSString *digit = sender.titlelabel.text;
Why is digit a pointer?
The type of your digit is id, which is just basically just a C pointer to a certain struct. All references to objects in Objective-C have this primitive type, regardless of the Class of the object. So the answer to your question is, unfortunately, because that's the way Objective-C works.
So whether you're declaring an NSString*, or an UITableViewController*, or MyClass*, your variable has type id. This is the primary means by which the language implements polymorphism. So, for example, the following declarations are equivalent:
NSString *digit;
id digit;
And it's true of method prototypes as well. These are equivalent:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(id)tableView:(id)tableView cellForRowAtIndexPath:(id)indexPath;
A variable of type id is not an object itself, it is a pointer to an object. It is the handle with which you manipulate an object. Objective-C does all of the class compatibility work at runtime.
Hope this helps. Any questions?
Updates
That's right: int, float, double, char, void, and the pointer combinations, are all C primitive types. You can and will still use these quite a bit, and they are just what they are in a C program. But Objective-C adds the id type as a way to bridge the gap between the primitive typing of C and the very high-level typing of objects by the Objective-C system. id itself is typedef'd as a pointer to a simple struct in objc.h. At the level of the compiler and the language itself, there really isn't too much meaning to the type. For example, you'll almost never declare an array of ids, certainly never perform any arithmetic with them.
In fact, it's not too far a stretch to say that Objective-C is just plain vanilla C with some added syntax (particularly, the square-bracket notation for method invocation), a few extra primitive types (id, IMP, SEL), and a big runtime library. It's this runtime library that handles all things Object-Oriented.
Anyway, to answer your question, when you're actually programming, you will most often (99% of the time) just use class names to declare your variables - NSString *, NSData *, UITableViewController *, and so on. And the compiler will know what you're talking about, and issue a warning if you write code that clearly tries to put an NSString* where an NSData* is expected. But the actual meaning of those types really exists only at runtime.
I've digressed a little, but I'm not sure where your understanding is failing you, so I thought I'd just explain things a bit. You might want to read Apple's The Objective-C Programming Language to get a feel for the language.
NSString is an Objective-C class and all object references in Objective-C are pointers. I would suggest reading through some of the documentation such as Learning Objective-C A Primer:
Notice the * in the first declaration. In Objective-C, object
references are pointers. If this doesn’t make complete sense to you,
don’t worry—you don’t have to be an expert with pointers to be able to
start programming with Objective-C. You just have to remember to put
the * in front of the variable names for strongly-typed object
declarations. The id type implies a pointer.
It's not a digit, it's the "text" from the label, which is (I'm guessing) a string of integers and such to express the time.
So, all NSString types are declared as pointers in Obj-c.
sender.titlelabel.text;
Returns a NSString *
Remember, it's the same as:
NSString *str = [sender.titlelabel getText];
Because text is too. Or more preceisly, because the getText message returns a pointer.
You can find an intersting about why it has to be a pointer:
NSString and Pointers
I Hope it will help you to understand it in a Objective-C way.

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 the meaning of id?

I am (trying to) learn Objective-C and I keep coming across a phrase like:
-(id) init;
And I understand id is an Objective C language keyword, but what does it mean to say "the compiler specifically treats id in terms of the pointer type conversion rules"?
Does id automatically designate the object to its right as a pointer?
id is a pointer to any type, but unlike void * it always points to an Objective-C object. For example, you can add anything of type id to an NSArray, but those objects must respond to retain and release.
The compiler is totally happy for you to implicitly cast any object to id, and for you to cast id to any object. This is unlike any other implicit casting in Objective-C, and is the basis for most container types in Cocoa.
id is a pointer to any Objective-C object (objc_object). It is not just a void pointer and you should not treat it as so. It references an object that should have a valid isa pointer. The values that can be stored in id are also not just limited to NSObject and its descendants, which starts to make sense of the existence of the NSObject protocol as well as the NSProxy class which does not even inherit from NSObject. The compiler will allow you to assign an object referenced by type id to any object type, assign any object type to id, as well as send it any message (that the compiler has seen) without warning.
id is a generic type. This means that the compiler will expect any object type there, and will not enforce restrictions. It can be useful if you're expecting to use more than one class of objects there; you can then use introspection to find out which class it is. id automatically assumes a pointer, as all objects in Objective-C are passed as pointers/references.
Some Additional Resources:
id vs NSObject vs id*
Objective-C Programming (Wikibooks)
Introspection
Dynamic Typing
id is a data type of object identifiers in Objective-C, which can
be use for an object of any type no matter what class does it have.
id is the final super type of all objects.
In java or c# we use like this
Object data = someValue;
String name =(Object)data;
but in objective c
id data= someValue;
NSString *name= data;
Yes and no. It's true that having id x designates x as a pointer, but saying that the pointer type conversion rules apply is wrong, because "id" has special type conversion rules. For example, with a void * pointer you can't do this:
void *x;
char *y = x; // error, this needs an explicit cast
On the contrary, it's possible with id:
id x;
NSString *y = x;
See more usage of type id in objective c examples.
In addition in the "modern" Objective C it's preferred to use instancetype instead of "id" on "init" methods. There's even an automatic conversion tool in Xcode for changing that.
Read about instancetype: Would it be beneficial to begin using instancetype instead of id?