If you take this method call for instance(from other post)
- (int)methodName:(int)arg1 withArg2:(int)arg2
{
// Do something crazy!
return someInt;
}
Is withArg2 actually ever used for anything inside this method ?
withArg2 is part of the method name (it is usually written without arguments as methodName:withArg2: if you want to refer to the method in the documentation), so no, it is not used for anything inside the method.
As Tamás points out, withArg2 is part of the method name. If you write a function with the exact same name in C, it will look like this:
int methodNamewithArg2(int arg1, int arg2)
{
// Do something crazy!
return someInt;
}
Coming from other programming languages, the Objective-C syntax at first might appear weird, but after a while you will start to understand how it makes your whole code more expressive. If you see the following C++ function call:
anObject.subString("foobar", 2, 3, true);
and compare it to a similar Objective-C method invocation
[anObject subString:"foobar" startingAtCharacter:2 numberOfCharacters:3 makeResultUpperCase:YES];
it should become clear what I mean. The example may be contrived, but the point is to show that embedding the meaning of the next parameter into the method name allows to write very readable code. Even if you choose horrible variable names or use literals (as in the example above), you will still be able to make sense of the code without having to look up the method documentation.
You would call this method as follows:
int i=[self methodName:arg1 withArg2:arg2];
This is just iOs's way of making the code easier to read.
Related
When would we ever need with in Kotlin if we can already use apply, run, also and let?
Can anyone give me a clear example?
In most situations, a with call can be transformed to a run like this:
with(foo) {
// some code ...
}
// is the same as:
foo.run {
// the same code ...
}
run and with will both return the lambda result, and will use foo as the lambda receiver.
However, I can think of one case where this wouldn't work - when foo declares its own run method that takes a lambda, e.g.
// having something like this isn't too uncommon, right?
fun run(x: () -> Unit) {}
The lambda type doesn't have to be exactly the same as the scope function run. Any function type should work. Then overload resolution wouldn't resolve to the built-in run.
You can force the resolution by doing some casts, but using with in this case is much better. Don't you agree?
I don’t think there’s any better example than with(context). Maybe it’s not clear if English isn’t one of your primary languages, but it semantically is translated into English much clearer than context.run when the object is being used to produce a result but isn’t the primary actor, so it makes code a little easier to read.
This of course raises the question of why run exists. Well, it semantically makes more sense in English when the object is the thing doing the action. In English, the context of an action is what you’re doing something with. But if the object is what is directly producing the result, then it is running the action.
Also, you can’t do ?.with.
Inside an Objective-C method, it is possible to get the selector of the method with the keyword _cmd. Does such a thing exist for the names of arguments?
For example, if I have a method declared as such:
- (void)methodWithAnArgument:(id)foo {
...
}
Is there some sort of construct that would allow me to get access to some sort of string-like representation of the variable name? That is, not the value of foo, but something that actually reflects the variable name "foo" in a local variable inside the method.
This information doesn't appear to be stored in NSInvocation or any of its related classes (NSMethodSignature, etc), so I'm not optimistic this can be done using Apple's frameworks or the runtime. I suspect it might be possible with some sort of compile-time macro, but I'm unfamiliar with C macros so I wouldn't know where to begin.
Edit to contain more information about what I'm actually trying to do.
I'm building a tool to help make working with third-party URL schemes easier. There are two sides to how I want my API to look:
As a consumer of a URL scheme, I can call a method like [twitterHandler showUserWithScreenName:#"someTwitterHandle"];
As a creator of an app with a URL scheme, I can define my URLs in a plist dictionary, whose key-value pairs look something like #"showUserWithScreenName": #"twitter://user?screenName={screenName}".
What I'm working on now is finding the best way to glue these together. The current fully-functioning implementation of showUserWithScreenName: looks something like this:
- (void)showUserWithScreenName:(NSString *)screenName {
[self performCommand:NSStringFromSelector(_cmd) withArguments:#{#"screenName": screenName}];
}
Where performCommand:withArguments: is a method that (besides some other logic) looks up the command key in the plist (in this case "showUserWithScreenName:") and evaluates the value as a template using the passed dictionary as the values to bind.
The problem I'm trying to solve: there are dozens of methods like this that look exactly the same, but just swap out the dictionary definition to contain the correct template params. In every case, the desired dictionary key is the name of the parameter. I'm trying to find a way to minimize my boilerplate.
In practice, I assume I'm going to accept that there will be some boilerplate needed, but I can probably make it ever-so-slightly cleaner thanks to NSDictionaryOfVariableBindings (thanks #CodaFi — I wasn't familiar with that macro!). For the sake of argument, I'm curious if it would be possible to completely metaprogram this using something like forwardInvocation:, which as far as I can tell would require some way to access parameter names.
You can use componentsSeparatedByString: with a : after you get the string from NSStringFromSelector(_cmd) and use your #selector's argument names to put the arguments in the correct order.
You can also take a look at this post, which is describing the method naming conventions in Objective C
I wasn't aware this syntax was valid.
+ (void) methodName:(TypeObject *)typeObject1:(TypeObject *)typeObject2;
Which is then called like so:
[object methodName:obj1:obj2];
I find it ugly and disturbing, but it builds.
Can someone point me at a reference which explains why this is valid.
FWIW the codebase (inherited) that this comes from, is rife with sloppy, lazy stuff, dozens of spelling errors and looks like it was formatted by someone with no need to ever read it again. (Thank you again uncrustify.)
This is a well-kown and documented feature (pdf, p. 14)
In principle, a Rectangle class could instead implement a setOrigin::
method with no label for the second parameter, which would be invoked
as follows:
[myRectangle setOrigin:30.0 :50.0]; // This is a bad example of multiple parameters
but apple discourage everbody of using parameter passing without keyword:
Use keywords before all arguments.
- (void)sendAction:(SEL)aSelector to:(id)anObject forAllCells:(BOOL)flag; -> Right.
- (void)sendAction:(SEL)aSelector :(id)anObject :(BOOL)flag; -> Wrong.
Why it was allowed by the creators of objective-C, I dont know. Maybe it has to do with the Smalltalk heritage.
Is it possible to call a function by name in Objective C? For instance, if I know the name of a function ("foo"), is there any way I can get the pointer to the function using that name and call it? I stumbled across a similar question for python here and it seems it is possible there. I want to take the name of a function as input from the user and call the function. This function does not have to take any arguments.
For Objective-C methods, you can use performSelector… or NSInvocation, e.g.
NSString *methodName = #"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];
For C functions in dynamic libraries, you can use dlsym(), e.g.
void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
function();
}
For C functions that were statically linked, not in general. If the corresponding symbol hasn’t been stripped from the binary, you can use dlsym(), e.g.
void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
function();
}
Update: ThomasW wrote a comment pointing to a related question, with an answer by dreamlax which, in turn, contains a link to the POSIX page about dlsym. In that answer, dreamlax notes the following with regard to converting a value returned by dlsym() to a function pointer variable:
The C standard does not actually define behaviour for converting to and from function pointers. Explanations vary as to why; the most common being that not all architectures implement function pointers as simple pointers to data. On some architectures, functions may reside in an entirely different segment of memory that is unaddressable using a pointer to void.
With this in mind, the calls above to dlsym() and the desired function can be made more portable as follows:
void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
(*function)();
}
I would like to know the difference between these two (sorry I do not know the name of this subject).
I come from C# where I was used to write System.data as well as classA.MethodA. I have already found out that in Cpp, with namespaces I need to use ::, with classmembers ->. But what about simple "."?
I have created System::data:odbc::odbcConnection^ connection. Later I was able to use connection.Open. Why not connection->open?
Im sorry, I am sure its something easily findable on the net, but I dont know english term for these.
Thank you guys
If you have a pointer to an object, you use:
MyClass *a = new MyClass();
a->MethodName();
On the other hand, if you have an actual object, you use dotted notation:
MyClass a;
a.MethodName();
To clarify the previous answers slightly, the caret character ^ in VC++ can be thought of as a * for most intents and purposes. It is a 'handle' to a class, and means something slightly different, but similar. See this short Googled explanation:
http://blogs.msdn.com/branbray/archive/2003/11/17/51016.aspx
So, in your example there, if you initialize your connection like:
System::Data::Odbc::OdbcConnection connect;
//You should be able to do this:
connect.Open();
Conversely, if you do this:
System::Data::Odbc::OdbcConnection^ connect1 = gcnew System::Data::Odbc::OdbcConnection();
connect1.Open(); // should be an error
connect1->Open(); //correct
The short answer: C++ allows you to manage your own memory. As such, you can create and manipulate memory, through usage of pointers (essentially integer variables containing memory addresses, rather than a value).
a.Method() means a is an instance of a class, from which you call Method.
a->Method() means a is a pointer to an instance of a class, from which you call Method.
When you use syntax like a->member, you are using a pointer to a structure or object.
When you use syntax like a.member, you are using the structure or object and not a pointer to the structure or object.
I did a quick google for you and THIS looks fairly quick and decent explanation.