I wanted to invoke a OC Class Method with an block in Swift 3.0:
#interface API : NSObject
+ (void)GetCommissionInfoWithModel:(CommissionInfoRequestModel*)model returnInfo:(void (^)(CommissionInfoResponseModel*resModel))callBackBlock;
I tried to invoke it like:
API.GetCommissionInfoWithModel(CommissionInfoRequestModel...
but I don't know how to continue. I know how to invoke a simple method like:
API.test()
API.test(para1:"1",para2:"2")
but with a block, it makes me confused.
I have tried:
let someModel: CommissionInfoRequestModel = CommissionInfoRequestModel.model()
but I got another error:
model()is unavailable : use object construction ‘BaseModel()
Yes the CommissionInfoRequestModel is inherited from "BaseModel", but why I can't use CommissionInfoRequestModel()?
Than I got an error below:
Cannot convert value of type '(CommissionInfoResponseModel) -> ()' to expected argument type '((CommissionInfoResponseModel?) -> Void)!'
when I used the code like:
API.GetCommissionInfoWithModel(someModel1){
(resModel: CommissionInfoResponseModel) in
// Response available in 'resModel' parameter...
}
Try this:
let someModel: CommissionInfoRequestModel = ...
API.GetCommissionInfoWithModel(someModel) {
resModel in
// Response available in 'resModel' parameter...
}
which is just syntax sugar for this longer form:
API.GetCommissionInfoWithModel(someModel, returnInfo: {
(resModel: CommissionInfoResponseModel?) in
...
})
In both versions, the last argument is a closure:
Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures in Swift are similar to blocks in C and Objective-C and to lambdas in other programming languages.
For more info, please see The Swift Programming Language book.
Related
In the book, "Swift Programming Language 3.0", it mentioned that types of closure include:
Global functions are closures that have a name and do not capture
any values
Nested function are closures that have a name and can
capture values from their enclosing function
Closure expression are
unnamed closure written in a lightweight syntax that can capture
values from their surrounding context
I was just wondering does a function that exist in class scope count as a closure? One can certainly pass around such function as an argument to other function, but is it a closure?
Yes! Absolutely! Here's an example that uses the lowercased() method of String.
let aClosure: (String) -> () -> String = String.lowercased
let anUpperCasedString = "A B C"
print(anUpperCasedString)
let aLowerCaseString = aClosure(anUpperCasedString)()
print(aLowerCaseString)
You can see that the type of this closure is (String) -> () -> String. This is because String.lowercased is completely unapplied, it has no clue what instance it's operating on.
Calling aClosure(anUpperCasedString) will return a closure that's now () -> String. Baked into it is the instance it'll operate on. Only when you call this new closure with no params (()), will it actually execute the body of lowercased(), operating on the instance you gave it in the previous step, and return you the String result.
As a consequence, this is also valid:
let aLowerCaseString = String.lowercased("QWERTY")()
It just does all the steps above in one inlined step.
This technique is called function currying. This post talks more about this technique (called function currying) as it applies to instance methods in Swift.
I try to understand the main concept of callbacks in swift
I have the following code:
typealias ImageHandler = (String,NSError?) -> Void
func PostOnSocialMedia(image:String?){
println(0)
Post({(image)->Void in
println(1)
})
println(2)
}
func Post(handler:ImageHandler){
println(3)
}
my code output is 0,3,2 and my question is why doesn't print the number 1.
It’s not printing 1 because you are passing in a function that is never called.
This:
Post({ (image)->Void in
println(1)
})
declares a temporary function (a “closure expression” – a quick easy way to declare anonymous functions, between the { }) that takes an argument of a (String,NSError?) pair, and returns nothing. Then it passes that function into the Post function.
But the Post function does nothing with it. For a function to run, it needs to be called. If you changed your Post function like so:
func Post(handler:ImageHandler){
println(3)
// call the handler that was passed in...
handler("blah",nil)
}
you’ll see it printing a 1.
Note, the image argument received by PostOnSocialMedia and the image argument variable inside the temporary function are two different variables – scoping rules mean the one declared inside the temp function masks the one in the outer scope. But they are very different (in fact, they’re different types – one is a string, and the other is a 2-tuple of a string and an error).
Try reading this for a short intro on first-order functions and closures in Swift.
I'm trying to understand, how does method signature in Objective-C is look like.
INTRO:
At first, lets break misunderstandings about question, what is it, method signature?
Method signature it is something, that helps compiler unambiguously identifies subroutine.
Am i right? :)
So in the C language signature is roughly equivalent to its prototype definition:
For example, we have function int printf( const char *format, ... ); in stdlib.
Signature of this function is printf.
In this case, we can't overload in C language, because compiler can't identify function with different argument types, so people decide to do some tricky thing like this:
long int labs (long int n);
int abs (int n);
double fabs (double x);
In the C++ language, method signature is class name, method name and method arguments.
So in this language we can overload methods.
PROBLEM
I can't get simple answer, what is method signature in Objective-C?!
I'm trying to use my logic...
1)At first, we can't overloading in Objective-C => method arguments is not part of method signature.
2)I tried to compile code with different return value:
#interface Foo : NSObject
- (CGFloat)method;
- (NSInteger)method;
#end
I got error in this case => return value is not part of method signature.
I tested different cases and got the answer, method signature in Objective-C is class name, method type ('+' or '-') and selector.
For example, we have method in class Foo (code below):
#interface Foo : NSObject
+ (void)methodWithArgument:(NSInteger)argument;
#end
So the signature of this method is +[Foo methodWithArgument:]
But then, i look at apple's documentation of NSMethodSignature (http://bit.ly/1tGR8zt)
An NSMethodSignature object records type information for the arguments
and return value of a method
Arguments and return value?! Only using arguments and return value, we can unambiguously identify method? It's very strange.
First thing. Who said that compiler can differentiate between 2 methods on the basis or its return type
so
#interface Foo : NSObject
- (CGFloat)method;
- (NSInteger)method;
#end
is wrong. Even in C or C++ you cannot overload method on the basis of its return type. Overloading can be performed on the basis of type of argument or number of arguments for a methods or both.
so over loading can be performed in this way only
#interface Foo : NSObject
-(ReturnType)methodNameHere:(int)argument;
-(ReturnType)methodNameHere:(int)argument secondArgumentDescription:(BOOL)anotherArgument;
-(ReturnType)methodNameHere;
compiler identifies different methods on the basis for number of arguments and their data type
Method signature is for developers and for runtime,
Not for compiler. (Compiler uses another technique to understand signatures)
you cannot identify methods that have the same name but different return types. If you call it while discarding the return value, which one should be called?
#interface Foo : NSObject
- (CGFloat)method;
- (NSInteger)method;
#end
Foo *foo = [Foo new];
[foo method]; // no use for return value here. Which implementation to call?
I've created a code sample that shows the issue I'm having:
class BindingExample {
public static void main(String[] args) {
Closure closure1 = {
printit.call("Hello from closure 1")
}
Closure closure2 = {
printit("Hello from closure 2")
}
Closure printit = { s ->
println("printing: "+s)
}
Binding binding = new Binding()
binding.setVariable("printit", printit)
closure1.delegate = binding
closure2.delegate = binding
closure1() //This works fine
closure2() //This does not.
//Why does .call() work and () alone not? Most documentation says they're the same.
}
}
Printit is a Closure, which the documentation indicates implements doCall and therefore is callable in short form via ().
However, when this closure is made available via binding to a delegate, only the long-form version of the call is permitted. The output is:
printing: Hello from closure 1
Exception in thread "main" groovy.lang.MissingMethodException: No signature of method: groovy.lang.Binding.printit() is applicable for argument types: (java.lang.String) values: [Hello from closure 2]
Can someone explain why this is the case? If possible, I'd like to also see how to make it so the short-form version works. I was able to make it work by defining printit as a proper static method (not a closure), but that won't work for my case because I actually need printit to be given some data available only inside of the method scope (not included in the example since my question relates to the binding itself).
As to WHY this is the case, I can't give a definite answer, unfortunately. There's some talk about implicit-"this" annotation, etc. It seems like it should work, but that there's some vagueness about what should be tried first (this-scope or delegate).
That the issue exists, currently, seems correct. I've found the following other resources that agree, with some discussion without resolution about why.
Nabble discussion about the issue:
http://groovy.329449.n5.nabble.com/Binding-Closure-property-not-called-as-method-td5562137.html
JIRA ticket resulting:
https://issues.apache.org/jira/browse/GROOVY-5367
I have a file with a module with some routines that take parameters and return unit, these routines have side-effects. I noticed that when accessing these f# routines from c# they're actually properties of type unit and when I try to access 1 property, it runs all properties in the module.
From the F# documentation all top level do bindings are run on type initialization.
What is the preferred way to write functions that should not be run on type initialization but are also not associated with other state i.e. a class with functions and member variables?
Should I put these functions inside a type and just have no records in the type?
Code example:
namespace test_space
open System.Diagnostics;
module test =
let test_1 =
Debug.WriteLine ("One")
let test_2 =
Debug.WriteLine ("Two")
I'm running this code with C#:
static void Main (string [] args)
{
Object o;
o = test.test_2;
}
And the output is:
One
Two
The problem is you didn't create functions but value bindings. test_1 is a value. test_1() is a function of type unit -> unit. Make sure you put () after the function name.
I don't fully understand the scenario you're describing - F# functions declared in a module will generally appear as methods and values will appear as properties. The code that is executed when you first access module (type initialization) is the initialization of values.
If you write just:
module Foo =
let Operation () =
printfn "hello"
...then calling Operation will be a method and calling Foo.Operation() will run the side-effect. If you can post some code that behaves unexpectedly, then someone can explain it.
Anyway, if you want to be sure about the behavior, you can write operations as static members of a class:
type Foo =
static member Operation() =
printfn "hello"
Then you can be sure that F# will compile them as static members of a class in a predictable way.