Is there a Swift equivalent to Objective-C's #encode?
For instance
#encode(void *) // -> #"^v"
Searching yielded nothing.
No, there isn't - because under the hood Swift classes don't use Objective-C introspection to do their work. There's no need to calculate this (like there is in Objective-C) in order to pass/call data.
However, if you need to use it dynamically at runtime (say, for interoperation with existing Objective-C methods) then you can either create an Objective-C call and pass the object through or (for simple types) write a lookup table.
The type encodings are listed at https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html which have the map, and it's possible to write a switch type statement that does the lookup.
But fundamentally if you have a type that you want to pass in and find it's objective c encoding type, you can use the NSObject's objCType method:
var i = 1 as NSNumber
String.fromCString(i.objCType)! == "q"
If you need to pass it through as an unmolested C string anyway, you may not even need to convert it back to a Swift string type.
Related
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)
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.
I have a C struct that contains a function pointer. Now, I have used this setup within C with no problems, but now I'm using this C struct in Objective-C and I need to pass a function (or selector) pointer that is defined in the Objective-C class.
1. Here is what I have for the Objective-C selector that needs to be passed as a pointer to the C function:
- (void)myObjCSelector:(int*)myIntArray
{
// Do whatever I need with myIntArray
}
2. And here is where I run into a wall, Within Objective-C I'm trying to pass the selector as a pointer to the C function call: In place of "myObjCSelectorPointer" I need the proper syntax to pass the selector as a function pointer in this C function call:
passObjCSelectorPointerToCContext(cContextReference, myObjCSelectorPointer);
I did investigate this issue, but could mainly find several different ways of doing similar things, but I couldn't find anything specific for calling C functions and passing an Objective-C selector pointer.
In objc a selector is not a function pointer. A selector is a unique integer that is mapped to a string in a method lookup table stored by the objc runtime. In the above case your method name would be myObjCSelector: and to get the unique selector for it you would type #selector(myObjCSelector:). However this would be of no use to you because it doesnt represent a particular implementation of a function.
What youre looking for is IMP. Refer to this SO question.
EDIT 2:
IMP myObjCSelectorPointer = (void (*)(id,SEL,int*))[self methodForSelector:#selector(myObjCSelector:)];
Then you can call the method using
myObjCSelectorPointer(self,#selector(myObjCSelector:),myIntArray);
However, what this means you will need to make sure that you add the pointer to self in the c function call passObjCSelectorPointerToCContext.
So it should look like this
passObjCSelectorPointerToCContext(cContextReference, self, myObjCSelectorPointer);
when called from within the object that contains the method.
It is important to note though that using IMP is almost never the right technique. You should try to stick with pure Obj-C. Obj-C is quite efficient after the first call to a message because it uses temporal caching.
EDIT 1:
It's useful to understand why objc works in this way. The Apple documents explain it in depth. However a short explanation is as follows:
When you send a message to an object such as [myobject somemethod] the compiler won't immediately know which particular implementation of somemethod to call because there might be multiple classes with multiple overriden versions of somemethod. All of those methods have the same selector, irrespective of its arguments and return values and hence the decision about which implementation of somemethod is deffered to when the program is running. [myobject somemethod] gets converted by the compiler into a C function call:
objc_msgSend(myobject, #selector(somemethod))
This is a special function that searches each myobject class layout to see whether that class knows how to respond to a somemethod message. If not it then searches that class's parent and so on until the root. If none of the classes can respond to somemethod then NSObject defines a private method called forward where all unknown messages are sent.
Assuming that a class can respond to the somemethod message then it will also have a particular pointer of type IMP that points to the actual implementation of the method. At that point the method will be called.
There is considerably more to this procedure than I have described but the outline should be enough to help you understand what the goal of a selector is.
One final point is that the reason method names are mapped to unique integers via the #selector directive is so that the runtime doesn't have to waste time doing string comparisons.
Basically, the answer is: Objective-C selectors are different from function pointers. You need two pieces of data to perform a selector. That is an object and the selector itself. You will need some glue to accomplish your task.
Check this question.
Do you have to use a function pointer? In Objective-C, you can get the function pointer to an arbitrary method implementation (known as an IMP), but this is extremely uncommon, and usually not a good idea. Calling objc_msgSend() directly is also not the greatest idea, because there are several different variants of objc_msgSend(), and the compiler automatically chooses different ones to use based on the return type of the method. Methods that return an object go through objc_msgSend(), but objects that return structs might go through objc_msgSend() or they might go through objc_msgSend_stret(). And if the method returns a double, then it goes through objc_msgSend_fpret()...
Documentation: Objective-C Runtime Reference: Sending Messages
Instead, I might recommend using a target-action pair, or using a block. Then you might do something like:
myContextRef->target = anObjcObject;
myContextRef->action = #selector(invokeMe:);
And when you're done, do:
[myContextRef->target performSelector:myContextRef->action withObject:someReturnInformation];
Or maybe use a block:
myContextRef->completionHandler = [^(id returnInformation) {
[anObjcObject invokeMe:returnInformation];
} copy];
And then when you're done, do:
myContextRef->completionHandler(someReturnInformation);
(and don't forget to -release the block when you free the context)
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.
When do you and when dont you need the * symbol (which is because in objective-c all variables like NSString are pointer variables)?
For example when do you need to do "NSString *" instead of just "NSString"?
In Objective-C, all object references are pointers, so you always need the pointer operator when you declare with an Objective-C object.
For other types, the use is exactly the same as in C. Use pointers when you want to pass data structures or primitive types by reference.
You use the asterisk for all Objective-C objects (such as NSDictionary, NSString, NSNumber).
For anything that is a primitive type (int, double, float) you don't need the asterisk. However, the NS prefix doesn't always mean that you must use an asterisk. Cocoa defines some structures (such as NSInteger, NSRect, NSPoint) that are are based on primitive types. You don't use the asterisk here either. An NSRect, for example, is just a structure of an NSPoint and NSSize, both of which are made up of 2 CGFloats (a primitive type).
You can pass a pointer to one of these primitive types or structures using the * notation.