Since we always use pointers to define variables, I was wondering if Objective-C is "pass by value", since like Java, the actual value would be passed by using its reference.
However, since it seems to be built up on top of C, would it have all the functionality of C?
C does not support pass-by-reference and Objective-C, being a strict superset of C doesn't either.
In C (and Objective-C) you can simulate pass-by-reference by passing a pointer, but it's important to remember that you're still technically passing a value, which happens to be a the value of a pointer.
So, in Objective-C (and C, for the matter) there is no concept of reference as intended in other languages (such as C++ or Java).
This can be confusing, so let me try to be clearer (I'll use plain C, but - again - it doesn't change in Objective-C)
void increment(int *x) {
*x++;
}
int i = 42;
increment(&i); // <--- this is NOT pass-by-reference.
// we're passing the value of a pointer to i
On the other hand in C++ we could do
void increment(int &x) {
x++;
}
int i = 41;
increment(i); // <--- this IS pass-by-reference
// doesn't compile in C (nor in Objective-C)
It is a strict superset of C.
It does the same as C.
It's one reason all Objects are actually pointers to structs.
Related
I am new to iOS programming, I am preferring Swift language and I don't know Objective C. While I am wandering through some library, I got a value of type UnsafeMutableRawPointer in swift, that is actually a String value with utf8 encoding.
So I just looked into the corresponding objective c class and the variable is declared as
#property (readonly) void *data;
So why there is void pointer and why it is converted as UnsafeMutableRawPointer?
Consider me as a noob in Objective c or c.
Thanks in advance
This whole thing might be quite a lot for a beginner to understand. So let's start with ObjectiveC syntax:
Property #property (readonly) void *data; exposes interfaces which says there must be a method of type - (void *)data which means an instance method returning a void pointer. A void pointer being a pointer to anything.
ObjectiveC is then kind of a pure C a level deeper. I will not check exact transformation but since C has no methods this is all done with functions or even pointers to functions. So somewhere down there there should be a function (let's say the name of this class is MyDataClass)
void *myDataClass_data(MyDataClass *self) { return self->_data; } // Or whatever the implementation is
So nothing really interesting is going on under the hood. The whole thing just returns a position in memory without any further information of what should be there. You as a developer must know and interpret it. From C (or ObjectiveC) this is very simply. A few examples:
char *aString = (char *)myDataClass.data; // A pure C string. Expected to be null terminated
int *arrayOfIntegers = (int *)myDataClass.data; // An array of integers
int thirdItem = arrayOfIntegers[2];
MyDataClass *nextItem = (MyDataClass *)myDataClass.data; // A pointer to another instance
for(MyDataClass *iterator = myDataClass; iterator != nil; iterator = (MyDataClass *)iterator.data) {}
I hope you get the picture. The point is that C and then also ObjectiveC are very unsafe when it comes to data types. You can basically convert anything into anything however you want it and it will compile. The problem is what will happen in runtime.
When looking at Swift things get much safer and you can not just say something like let integer: Int = myDataClass as Int. You can force cast it and it will crash. Or you can do optional cast and it will return nil.
So once transitioned from C/ObjectiveC you will receive an unsafe mutable raw pointer. That means it got a position in memory witch it has no idea about what it is and how to use it. You may try to convert it to anything you want but it is unsafe as it will ignore all type checking. It is mutable probably because data it holds may be changed at any given time by any system. It is raw as it holds no additional information (like it's a string). And it's a pointer because it only points to a position in memory.
(All the snippets are symbolical to explain what goes on under the hood. Please do not take them literal)
I am familiar with C and am now learning Objective-C.
I often use function pointers
void (*callback)(int*restrict, char*restrict)
Will that be usable in Objective-C? Especially in structs, like so:
struct mytype myvar = {
.first = myCallback;
.second = myCallback2;
}
Also, I wish to have function prototypes like
void function(int * restrict a, char * restrict b);
char * function (char * a);
...
Are there no problems with using this style?
Clang (the default compiler used by Xcode) claims C11 support for Objective C (See Language Compatibility).
This means function pointers, restrict, structs, and declarations will all work as you would expect.
One word of advice: don't fight the system; it will create more work for yourself and less reliable software for your users. Programmers should be like water.
Empty your mind, be formless, shapeless — like water. Now you put water in a cup, it becomes the cup; You put water into a bottle it becomes the bottle; You put it in a teapot it becomes the teapot. Now water can flow or it can crash. Be water, my friend.
— Bruce Lee
Yes.
You can use any C strategy that you choose in your Objective-C app. You will still have to write some Objective-C in order to start your UIApplication (or use a third-party tool to do it for you).
One thing to keep in mind, though, is that int will be a different length depending on the machine and you should explicitly choose int32_t or int16_t or int8_t if you really don't want to use the NSInteger typedef that abstracts this machine difference.
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Operator overloading in C
If I have a struct:
typedef struct myStruct {
...
} myStruct;
myStruct myStructAdd(myStruct a, myStruct b);
I need something like this:
#define myStruct a + myStruct b myStructAdd(a, b)
// NOTE this code does NOT WORK. This is what the question is asking.
To make this syntax valid:
myStruct a;
myStruct b;
myStruct c = a + b;
Is there any way to use a #define to do this?
EDIT:
I'm not asking for alternatives to the + syntax. What I'm asking is if, and how, the preprocessor can be used to rewrite the plus syntax to standard C syntax on compile.
i.e. something like #define myStruct a + myStruct b myStructAdd(a, b) which turns myStructA + myStructB into myStructAdd(myStructA, myStructB) on compile.
Operator overloading simply isn't a feature of C or Objective-C. C++ allows you to define arbitrary behaviour for operators and custom types. In Objective-C, if two objects can be added together, then usually there is a method for that:
Foo *result = [foo1 fooByAddingFoo:foo2];
Or, if the class is mutable:
Foo *foo1 = [Foo fooWithBar:bar];
[foo1 addFoo:foo2];
If operator overloading is a must-have feature, use C++ instead, or use Objective-C++ (but keep in mind that C++ classes and Objective-C objects are totally and fundamentally different).
Edit:
The C proprocessor is conceptually very simple, and it knows very, very little about C's syntax, and nothing at all about C's types. If you wanted to overload an operator using the preprocessor, then it would have to learn every type (including custom types) used in your code, and it would have to perform static type checking in order to determine which function to invoke, and this is something that is way out of the scope of the preprocessor.
It's an interesting idea, but it's simply not possible.
There is no way for you to do that using the preprocessor. Also, as far as I known, there is no other feature that would provide this in objective C.
However, if you would use C++ (or objective-C++, which give you all features of both Objective C and C++) you could define an operator+, as follows:
struct myStruct
{
myStruct operator+(myStruct const & other)
{
return ...;
}
}
If you limit your question to the preprocessor then the answer is that it is impossible due to the fact that to define a macro that takes in arguments you have to have a parentheses macro like
#define __DO_STH(par1,par2)
Operator overloading the way you think of it does not use parentheses so you can not create any such macros
The only way to do that would be to make a simple parser which would be reading your code and whenever it encountered the structs you need being added with a plus sign spit out C code that replaces that with the function, but why do that and not use C++ where it's natively supported?
Also unless you are asking for purely academic purposes, it is my honest opinion that operator overloading always does more bad than good and is better avoided.
The only way I know is to use Objective-C++. To do this, give your implementation file the extension "mm" and you're good to go.
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.