Home > database >  How rewrite Objective-C Macro expand with swift
How rewrite Objective-C Macro expand with swift

Time:11-30

The Objective-C Macro is like:

#define CALL_FUNC(classname, times, classfuncWithParamter) \ 
{\
     for (int i = 0; i< times; i  ) {\
          [classname classfuncWithParamter]\
     }\
}\

calling for Objective-C:

CALL_FUNC(AnClass, 10, setName:@"test" withPhone:12345)

What puzzles me is this for-loop call func, Macro can do text substitution to do this

What is the best way deal with this Macro in Swift?

CodePudding user response:

As people have stated in the comments, you'll need to use generics and closures. The trick is that you'll have to declare the "macro" multiple times if you want to support multiple numbers of parameters:

// for functions with no arguments
func call<T>(times: Int, _ f: () -> T) {
    for i in 0..<times {  f() }
}

// for functions with one argument
func call<A, T>(times: Int, _ f: (A) -> T, _ arg: A) {
    for i in 0..<times { f(arg) }
}

// for functions with two arguments
func call<A1, A2, T>(times: Int, f: (A1, A2) -> T, _ a1: A1, _ a2: A2) {
    for i in 0..<times { f(a1, a2) }
}

// for functions with three arguments
func call<A1, A2, A3, T>(times: Int, f: (A1, A2, A3) -> T, _ a1: A1, _ a2: A2, _ a3: A3) {
    for i in 0..<times { f(a1, a2, a3) }
}

// and so on...

For the sample from your question, the call would look something like this:

call(times: 10, AnClass.setName(_:withPhone:), "test", 12345)

, or you can pass a closure, and make the code more readable, like this:

call(times: 10) { AnClass.setName("test", withPhone: 12345) }

, and if you choose this road you can keep only the first call definition, the one without arguments: func call<T>(_ times: Int, f: () -> T). Calling the desired function within a closure is also more flexible, as you can support any numbers of arguments within that closure.

  • Related