Type encoding string for protocol method - objective-c

I'm trying to get a signature -- either an NSMethodSignature object or at least the type encoding string -- for a method declared in a protocol.
Asking the Protocol object itself isn't possible, since a) it doesn't implement methodSignatureForSelector:, and b) (as noted by Kevin below) it's deprecated.
The runtime function protocol_getMethodDescription returns a struct objc_method_description, which isn't described anywhere in the docs. It's in a public header, though -- <objc/runtime.h>:
struct objc_method_description {
SEL name;
char *types;
};
It seems reasonable to assume that the types string in there is going to be the same kind of signature encoding string used elsewhere, such as that expected by +[NSMethodSignature signatureWithObjCTypes:], and indeed, it looks correct.
What I can't track down is an actual, verifiable connection between that string and the type encoding process.
I can't think what else it would be, but still, do I have any justification for relying on this types string to be valid for interaction with other objects/functions on the same runtime? Note that I'm not writing encoding strings myself or expecting them to have a given format or value -- I only want to pass them from one part of the runtime/framework to another, i.e., retrieve an encoding string from a protocol and a) use it to generate an NSMethodSignature object if one isn't otherwise available, and possibly b) compare it to that of a runtime-generated NSInvocation (i.e., in -forwardInvocation:).

Using Protocol as an object is deprecated. If you check the header <objc/Protocol.h> you'll see that pretty much everything on it is either not available in OBJC-2 or is deprecated as of OS X 10.5. What you can do is use protocol_getMethodDescription(), as you suggested, and pull out the types field. I'm not sure if it's actually officially documented that this is the type encoding of the method, but that is indeed what it is.

Related

What is this Kotlin type: (String..String?)

IntelliJ is showing me context hints that my variables are of type (String..String?). I cannot find any mention of it on the internet, what is this type?
(String..String?) represents a flexible type with lower bound String and upperbound String? (nullable string). This is not valid Kotlin code (it's not denotable) but it is used in the compiler internals and thus in IntelliJ's hints sometimes.
(On the JVM we often see platform types using ! as in String!, which are a more specific case of flexible types)
It's Kotlin's way of saying it doesn't know whether the String type declared for payload.email is nullable or not (for instance if this is declared in Java, which doesn't distinguish those), and yet it doesn't want to enforce either of those, for convenience (hence "flexible").
As the name suggests, flexible types are flexible — a value of type (L..U) can be used in any context, where one of the possible types between L and U is needed
This means that even though the actual type of the value is "somewhere between String and String?", values of this type can be used even in places expecting String, even though the real type of that value may be String? and thus the value could be null.
This is useful because assuming it is String would mean that null checks would be marked as redundant, and assuming it is String? would force the developer to write null checks everywhere, even though they might know that this particular Java method cannot return null.
In general, it's a good practice to explicitly declare the type of a variable that you get from Java, to avoid the propagation of the platform type and the uncertainty (and unsafety) that comes with it:
val email: String = payload.email // if you know it cannot be null
val email: String? = payload.email // if you don't know

Understanding Solr charTermAttr methods

I can across a copy methods from charTermAttr from the org.apache.lucene.analysis.tokenattributes.CharTermAttribute library.
Can anyone explain what copyBuffer and buffer does for charTermAttr? The documentation isn't very clear. If you could provide an example that would be great too!
CharTermAttributeImpl keeps internally a char array and a length variable that represents the internal term.
The copyBuffer method writes over this array by using the char array provided with the respective offset and length params.
The buffer method returns the internal array that you can directly modify. Additionally, you can get the term representation as a string by calling the attribute's toString method
Have a look at the javadocs for more details: http://lucene.apache.org/core/4_9_0/core/org/apache/lucene/analysis/tokenattributes/CharTermAttribute.html

Do string literals in different files have the same memory address?

I'm using objc_[sg]etAssociatedObject(), and this function uses a memory address as a key. If I pass the same string literal - e.g. "UIImageForTexture" - into the function from two different files, will the two string literals have:
the same memory address?
different memory addresses?
it depends on some other factors.
it's undefined.
I can do this more explicitly by sticking the literal in a file somewhere and referring to it via an extern but I'd like to know if I can avoid having to do that.
This is going to be an implementation defined behavior from the C99 draft standard section 6.4.5 String literals paragraph 6 says:
It is unspecified whether these arrays are distinct provided their elements have the
appropriate values. If the program attempts to modify such an array, the behavior is
undefined.
It's whether two string literals with same content (e.g. char *p1="abc; char *p2="abc";) have the same address or different address is an implementation detail. p1 and p2 may be equal or may not be equal. C standard guarantees neither of them.
So the answer is (3) It depends on the implementation/optimization.
Instead of passing string literals directly, you can use pointers to them and pass them instead. That way, you can reliably handle them and not worry about (1) and (2).
This may be of interest: Addresses of two pointers are same?

Exclamation operator?

I'm learning D and have seen a lot of code like this:
ushort x = to!ushort(args[1]);
I assume this casts args[1] to ushort, but what's the difference between this and cast(ushort)?
EDIT: And what other uses does the exclamation mark operator have?
In D,
to!ushort(args[1])
is shorthand for the template instantiation
to!(ushort)(args[1])
and is similar to
to<ushort>(args[1])
in languages like C++/Java/C#.
The exclamation point is to note the fact that it's not a regular argument, but a template argument.
The notation does not use angle brackets because those are ridiculously difficult to parse correctly for a compiler (they make the grammar very context-sensitive), which makes it that much more difficult to implement a correct compiler. See here for more info.
The only other use I know about is just the unary 'not' operation (e.g. false == !true)... I can't think of any other uses at the moment.
Regarding the cast:
cast(ushort) is an unchecked cast, so it won't throw an exception if the value is out of range.
to!ushort() is a checked cast, so it throws an exception if the value is out of range.
The exclamation mark here is not an operator, it is just a token part of the explicit template instantiation syntax (described in detail here).
std.conv.to (docs) is a function template for converting between arbitrary types. It is implemented entirely in the library and has no special support in the language. It has a broader and different scope compared to the cast operator.
The to template takes two type parameters; a "to" type and a "from" type, in that order. In your example, the template is explicitly instantiated with the single type argument ushort for the "to" parameter, and a second type argument string (assuming args comes from the first parameter to main) is automatically inferred from the regular function argument passed to the function (args[1]) as the "from" parameter.
The resulting function takes a string parameter and returns a ushort parsed from that string, or throws an exception if it failed. The cast operator will not attempt this kind of high-level conversion.
Note that if there is more than one explicit template parameter, or that parameter has more than one token in it (ushort is a single keyword token), you must wrap the template parameter list in parentheses:
ushort result;
result = to!(typeof(result))(args[1]);
In this example, typeof, (, result and ) are four separate tokens and the parentheses are thus required.
To answer your last question, the ! token is also used for the unary not operator, unrelated to template instantiations:
bool yes = true;
bool no = !yes; // 'no' is false
You already got two excellent answers by jA_cOp and Merhdad. I just want answer directly to the OP question (what's the difference between this and cast(ushort)?) - The difference is that cast(ushort)args[1] will not work (you cannot cast from a string to an uint just like that), while the to!(type)(param) template knows what to do with the string and how to convert it to the primitive type.

Does static typing mean that you have to cast a variable if you want to change its type?

Are there any other ways of changing a variable's type in a statically typed language like Java and C++, except 'casting'?
I'm trying to figure out what the main difference is in practical terms between dynamic and static typing and keep finding very academic definitions. I'm wondering what it means in terms of what my code looks like.
Make sure you don't get static vs. dynamic typing confused with strong vs. weak typing.
Static typing: Each variable, method parameter, return type etc. has a type known at compile time, either declared or inferred.
Dynamic typing: types are ignored/don't exist at compile time
Strong typing: each object at runtime has a specific type, and you can only perform those operations on it that are defined for that type.
Weak typing: runtime objects either don't have an explicit type, or the system attempts to automatically convert types wherever necessary.
These two opposites can be combined freely:
Java is statically and strongly typed
C is statically and weakly typed (pointer arithmetics!)
Ruby is dynamically and strongly typed
JavaScript is dynamically and weakly typed
Genrally, static typing means that a lot of errors are caught by the compiler which are runtime errors in a dynamically typed language - but it also means that you spend a lot of time worrying about types, in many cases unnecessarily (see interfaces vs. duck typing).
Strong typing means that any conversion between types must be explicit, either through a cast or through the use of conversion methods (e.g. parsing a string into an integer). This means more typing work, but has the advantage of keeping you in control of things, whereas weak typing often results in confusion when the system does some obscure implicit conversion that leaves you with a completely wrong variable value that causes havoc ten method calls down the line.
In C++/Java you can't change the type of a variable.
Static typing: A variable has one type assigned at compile type and that does not change.
Dynamic typing: A variable's type can change while runtime, e.g. in JavaScript:
js> x="5" <-- String
5
js> x=x*5 <-- Int
25
The main difference is that in dynamically typed languages you don't know until you go to use a method at runtime whether that method exists. In statically typed languages the check is made at compile time and the compilation fails if the method doesn't exist.
I'm wondering what it means in terms of what my code looks like.
The type system does not necessarily have any impact on what code looks like, e.g. languages with static typing, type inference and implicit conversion (like Scala for instance) look a lot like dynamically typed languages. See also: What To Know Before Debating Type Systems.
You don't need explicit casting. In many cases implicit casting works.
For example:
int i = 42;
float f = i; // f ~= 42.0
int b = f; // i == 42
class Base {
};
class Subclass : public Base {
};
Subclass *subclass = new Subclass();
Base *base = subclass; // Legal
Subclass *s = dynamic_cast<Subclass *>(base); // == subclass. Performs type checking. If base isn't a Subclass, NULL is returned instead. (This is type-safe explicit casting.)
You cannot, however, change the type of a variable. You can use unions in C++, though, to achieve some sort of dynamic typing.
Lets look at Java for he staitically typed language and JavaScript for the dynamc. In Java, for objects, the variable is a reference to an object. The object has a runtime type and the reference has a type. The type of the reference must be the type of the runtime object or one of its ancestors. This is how polymorphism works. You have to cast to go up the hierarchy of the reference type, but not down. The compiler ensures that these conditions are met. In a language like JavaScript, your variable is just that, a variable. You can have it point to whatever object you want, and you don't know the type of it until you check.
For conversions, though, there are lots of methods like toInteger and toFloat in Java to do a conversion and generate an object of a new type with the same relative value. In JavaScript there are also conversion methods, but they generate new objects too.
Your code should actally not look very much different, regardless if you are using a staticly typed language or not. Just because you can change the data type of a variable in a dynamically typed language, doesn't mean that it is a good idea to do so.
In VBScript, for example, hungarian notation is often used to specify the preferred data type of a variable. That way you can easily spot if the code is mixing types. (This was not the original use of hungarian notation, but it's pretty useful.)
By keeping to the same data type, you avoid situations where it's hard to tell what the code actually does, and situations where the code simply doesn't work properly. For example:
Dim id
id = Request.QueryString("id") ' this variable is now a string
If id = "42" Then
id = 142 ' sometimes turned into a number
End If
If id > 100 Then ' will not work properly for strings
Using hungarian notation you can spot code that is mixing types, like:
lngId = Request.QueryString("id") ' putting a string in a numeric variable
strId = 42 ' putting a number in a string variable