Swift replacement for Objective-C macro

2019-07-28 18:27发布

问题:

I busy rewriting an app in Swift and would like to convert the following macro to Swift code.

#define FLOG(format, ...)               NSLog(@"%@.%@ %@", [self class], NSStringFromSelector(_cmd), [NSString stringWithFormat:format, ##__VA_ARGS__])

How can I define this as a Swift function such that I can use if anywhere for debug logging purposes, or is there an alternate way to achieve the same thing?

回答1:

The easiest way is probably to take advantage of string interpolation and use:

func FLOG(message:String, method:String = __FUNCTION__) {
    println("\(method): \(message)")
}

Then you usage is similar to:

FLOG("Illegal value: \(value)")

Having the method argument default to __FUNCTION__ means that it will normally be replaced with the calling function name. Other automatic variables that you could use include __FILE__, __LINE__ and __COLUMN__. Unfortunately __PRETTY_FUNCTION__ is no longer available.

If you want more control over the formatting of the message than string interpolation allows, take a look at this question which demonstrates simplifying access to printf-style formatting in Swift, and would let you do:

FLOG("Illegal value: %x" % [value])

See also this post from Apple that addresses using __FILE__ and __LINE__ in assert



回答2:

Apple's answer to the removal of macros and something new to replace them is that nothing like macros will be available in swift. The closest you can get is to replace #define with a global let variable.

Example: instead of #define CONSTANT 0 you can write let CONSTANT = 0

Whereas, if you want to pass arguments inside a macro, that feature will no longer be available as considered bad programming practice. What you can do instead is create a function.



标签: macros swift