What is the swift equivalent to _cmd? - ios

I want to get current method name to use in a format message similar to this one
[NSExeception raise:NSInternalInconsistencyException format:#"You must override %# in a subclass", NSStringFromSelector(_cmd)]
Also, I want to use _cmd to set associated object. I appreciate any idea.

NSStringFromSelector(_cmd); // Objective-C
print(#function) // Swift 4, 5

There is no Swift equivalent of _cmd. There is little reason to use it in Swift.
Consider _cmd in Objective-C. When is it useful? Most of the time, the value of _cmd would be the same as the name of the method that the code is in, so it is already known at compile time, and there is no need for a runtime value. Here are some possible cases when _cmd is useful in Objective-C:
In a macro. The macro is expanded in the code, so if _cmd appears in the macro, then it is inserted into the source where it is used, and so the method name can be used inside the macro. However, such macros do not exist in Swift. Plus macros are compile-time, so a compile-time mechanism like __FUNCTION__ would work similarly.
You can define a C function that takes self and _cmd, and use it (the same function) as the implementation of multiple methods, by adding it using class_addMethod and class_replaceMethod, and the _cmd inside the function will help distinguish between the different method calls. However, class_addMethod and class_replaceMethod are not available in Swift.
Method swizzling is also a process that messes with the implementation of a method. Since in swizzling you swap the implementations of two methods, _cmd will help reveal the actual method name used in the call, which may not match the method that the code is in in the source code, since implementations are swapped. I guess method swizzling may still be possible in Swift, since method_exchangeImplementations is still available in Swift. But in method swizzling, the method you swap in is tailored for the method it is swapping with, so if it is called, there is no ambiguity which method name is being called.
In the case where you manually get the IMP (implementing function) of a method, and manually call it with a different selector. In this case, the inside of the function can see the different selector in _cmd. However, you don't have to worry about this in Swift because the methods that get the IMP are unavailable.

Related

What does manipulating behaviour at runtime mean?

I have learned that using objective C's message dispatch system you can manipulate behaviour at runtime, such as method swizzling or even create classes at runtime.But what does it mean actually to change behaviour at runtime?
Predominantly it means two things - the classes and their implementation are defined in the runtime.
Methods
Objective-C uses dynamic dispatching. When a method is invoked, the runtime actually sends a message (via family of objc_msgSend functions) and looks for corresponding method in a class methods table. Even if a method wasn't implemented for a class, dynamic nature of the Objective-C allows to handle or redirect the message by overriding resolveInstanceMethod:, forwardingTargetForSelector: or forwardInvocation: methods. You can even add a method in runtime using class_addMethod function or exchange existing implementation of two methods using method-swizzling approach (method_exchangeImplementations function).
Classes
Thanks to dynamic traits of Objective-C you can change not only methods but also add/set/remove properties and ivars of a class. You can change even a class of an instance in runtime using object_setClass function.
There are much more methods that reveal full dynamic power of the Objective-C. You can refer to Objective-C Runtime page for more details about what you can do with them.
Objective-C besides running you code as you expect gives you a lot of possibilities to manipulate it’s behaviour at runtime.
Basically you can create a class from scratch and add some methods/properties to it when your app is running, or change the implementation of an existing selectors — also known as method swizzling.
By the way, you can find more information here:
https://docs.swift.org/swift-book/LanguageGuide/AdvancedOperators.html

Difference between selector and SEL and method call [ ]? [duplicate]

What the difference between a method, a selector and a message in Objective-C?
This is a great question.
Selector - a Selector is the name of a method. You're very familiar with these selectors: alloc, init, release, dictionaryWithObjectsAndKeys:, setObject:forKey:, etc. Note that the colon is part of the selector; it's how we identify that this method requires parameters. Also (though it's extremely rare), you can have selectors like this: doFoo:::. This is a method that takes three parameters, and you'd invoke it like [someObject doFoo:arg1 :arg2 :arg3]. There's no requirement that there be letters before each part of the selector components. As I said, this is extremely rare, and you will not find it used in the Cocoa frameworks. You can work with selectors directly in Cocoa. They have the type SEL: SEL aSelector = #selector(doSomething:) or SEL aSelector = NSSelectorFromString(#"doSomething:");
Message - a message is a selector and the arguments you are sending with it. If I say [dictionary setObject:obj forKey:key], then the "message" is the selector setObject:forKey: plus the arguments obj and key. Messages can be encapsulated in an NSInvocation object for later invocation. Messages are sent to a receiver. (ie, the object that "receives" the message).
Method - a method is a combination of a selector and an implementation (and accompanying metadata). The "implementation" is the actual block of code; it's a function pointer (an IMP). An actual method can be retrieved internally using a Method struct (retrievable from the runtime).
Some other related things that you didn't ask for:
Method Signature - a method signature represents the data types returned by and accepted by a method. They can be represented at runtime via an NSMethodSignature and (in some cases) a raw char*.
Implementation - the actual executable code of a method. Its type at runtime is an IMP, and it's really just a function pointer. iOS 4.3 includes a new ability to turn a block into an IMP. This is really cool.
One of the fun things to realize is that the name of a method (the selector) is distinct from the implementation of the method (the IMP). This means that you can swap them around, if you're feeling daring. You can also add and remove methods at runtime, because all you're doing is editing an entry in a hash table: the key is the selector, and the value is the IMP of the method. This allows you to do some really crazy and trippy stuff. It's not for the faint of heart. :)
A method is the implementation which is run when an object or class is asked to perform some action. It is in the scope of its containing class and is therefore different when referenced through some other class. A selector is an identifier which represents the name of a method. It is not related to any specific class or method, and can be used to describe a method of any class, whether it is a class or instance method.
Simply, a selector is like a key in a dictionary. It can tell you what method someone is talking about, but only if you also have the dictionary itself (the class or object). The method is what you get when you ask for the value from the dictionary using the selector as a key.
This site has a good overview of all the terminology in question: http://www.otierney.net/objective-c.html
Check out the link, but I'll give a quick summary:
A method is essentially like a method of function that you are used to in your favourite programming language.
A message (from the article) "A message can be dynamically forwarded to another object. Calling a message on an object in Objective-C doesn't mean that the object implements that message, just that it knows how to respond to it somehow via directly implementing it or forwarding the message to an object that does know how to."
Selectors can mean two things. It can refer to the name of a method, or "refers to the unique identifier that replaces the name when the source code is compiled. Compiled selectors are of type SEL." (from: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html)

can C function call objective-C class method?

id object_pointer;
(obj init method)...
object_pointer = self;
void some-c-function( void )
{
// Calling a class method from this C function:
[Some_Obj_C_Class class_method];
// or to calling an object method:
[object_pointer object_method];
}
I have to write my highest level code in C functions so that part can be eventually ported to an embedded system. I'm using iPads to simulate the hardware that's not available yet.
A C function can most certainly call an Objective-C method. In fact, a C function can even be an Objective-C method. Talking about how that works gets into the Objective-C runtime, a slightly related topic. An Objective-C method with no arguments can be thought of like a C function with exactly two arguments: self and _cmd. At compile time, Objective-C method calls are translated into calls to one of the objc_msgSend functions, which takes a selector and an object, in addition to any method arguments.
One thing that may be confusing is that because self is a sort of hidden argument in most methods, it will be inaccessible from a standard C function, even if you have it defined inside the #implementation of your object. As long as you are using Objective-C variables that are accessible in the scope of your function, you can make Objective-C method calls.

performSelector or directly

I understand that these both are bit similar, but there must be any internal difference between two,
[anObject performSelector:#selector(thisMethod:) withObject:passedObject];
is equivalent to:
[anObject thisMethod:passedObject];
Please tell me what is the differnce in terms of compilation, memory etc.
The performSelector family of methods are for special cases, the vast majority of method invocations in Obj-C should be direct. Some differences:
Indirect: When using performSelector to invoke a method you have two method invocations; that of performSelector and the target method.
Arguments are objects: When invoking via performSelector all arguments must be passed as objects, e.g. if invoking a method which takes a double then that value must be wrapped as an NSNumber before being passed to performSelector. The performSelector methods unwraps non-object arguments before calling the target method. In direct invocation no wrapping or unwrapping is required.
Only two arguments: The performSelector family only includes variants which pass 0, 1 or 2 arguments so you cannot use them to invoke a method which takes 3 or more arguments.
You probably see most of the above as negatives, so what are the benefits?
Dynamic selector: The performSelector family allow you to invoke a method which is not known until runtime, only its type need be known (so you can pass the right arguments and get the right result); in other words the selector argument may be an expression of type SEL. This might be used when you wish to pass a method as an argument to another method and invoke it. However if you are compiling with ARC using dynamic selectors is non-trivial and usually produces compiler warnings, as without knowing the selector ARC cannot know the ownership attributes of the arguments.
Delayed execution: The performSelector family includes methods which invoke the method after a delay.
In general use direct method invocation, only if that does not give you what you require do you need to consider the performSelector family (or its even more esoteric cousins).
performSelector:withObject: will be slightly slower than calling the method directly. The indirection also means that the compiler can't do proper type checking. With ARC enabled, you'll also run into issues where the compiler will complain because it is impossible to determine exactly what the memory management policy might be.
In general, such indirection -- often called reflection but more accurately referred to as meta-programming -- is to be avoided exactly because it moves what should be compile time detectable failures to runtime failures.
Such dynamism is only needed when the name of the selector -- the name of the method -- being called cannot be determined at compile time. It should not be used for #optional methods in protocols nor should it be used during delegation (in both cases, respondsToSelector: + a direct method call are a far better pattern to employ).
The performSelector: method allows you to send messages that aren’t determined until runtime. For more info read this.
If your app wants to make use of reflection, where in by changing some values in configuration file you want to invoke a different method (Different adapters). Or based on object type you would like to invoke a different method on runtime.
If you developing a customizable product this a powerful feature.
I like to use [id performSelecter:selector withObject] when declare and implements a custom protocol,and delegate pattern, its also an use case, where we should use performselector rather then direct calling the method...

Why doesn't Xcode complain about undeclared methods when using #selector?

Why are warnings generated when calling methods undeclared in a class interface using conventional means, but not when calling methods using #selector? Is it because selectors can be executed by a different caller than self?
For example:
-(void) doStuff
{
[self doNow]; // Warning: instance method not found
SEL sel = #selector(doNow); // no warnings
}
-(void) doNow {} // this method is not declared in the interface
The "Undeclared Selector" warning is turned off by default. I don't know why. You can turn it back on in the Build Settings.
The documentation for this settings reads:
Warn if a "#selector(...)" expression referring to an undeclared selector is found. A selector is considered undeclared if no method with that name has been declared before the "#selector(...)" expression, either explicitly in an #interface or #protocol declaration, or implicitly in an #implementation section. This option always performs its checks as soon as a "#selector(...)" expression is found, while -Wselector only performs its checks in the final stage of compilation. This also enforces the coding style convention that methods and selectors must be declared before being used. [GCC_WARN_UNDECLARED_SELECTOR, -Wundeclared-selector]
A similar question was asked on SO a few weeks ago.
This is basically because selectors are late-bound. They're not looked up until runtime. There are options for forcing verification during compilation. The question I linked to has some more information on how you can do that.
The way #selector works by default is you are telling the compiler; trust me I have this method somewhere in my class. Its the same concept if you do #class yourclassname instead of importing the .h file which contains the class.
This is because the compiler needs to know the signature of the method in order to call it (i.e. [self doNow];), because such a call translates to either a call to objc_msgSend or objc_msgSend_stret depending on whether the method signature has a return type of a struct or not. (Remember the difference between the selector (simply the name with the colons in it, but with no types) and the signature (the types) of a method.) So it needs to warn because it could be calling the wrong function if it doesn't know.
However, just getting a selector (#selector(...)), it doesn't need to know the types. The selector is simply a name, and you've provided the name. It's all about what you use the selector for. If you use it in performSelector:, it also doesn't need to know the types, because that method only works for methods with argument and return types of objects, so there is no ambiguity. Hence there is no need for a warning.

Resources