我有一个我使用的预处理器宏:
@implementation MyClass
- (void)methodA
{
MyLog("Hello, method A!");
}
- (void)methodB
{
MyLog("Hello, method %@!", @"B");
}
@end
在宏观扩张后,它看起来像:
@implementation MyClass
- (void)methodA
{
; NSLog([NSString stringWithFormat:@"%s - %@", __func__, "Hello, method A!"]); ;
}
- (void)methodB
{
; NSLog([NSString stringWithFormat:@"%s - %@", __func__, "Hello, method %@!"], @"B"); ;
}
@end
这将导致这些方法被打印出来用于各自的方法:
-[MyClass methodA] - Hello, method A! -[MyClass methodB] - Hello, method B!
我想将其更改为一组Objective-C 或Swift 方法,我可以用相同的方式调用它,并给出相同的结果。我不想管理一个对象,所以这些应该是类/静态方法。 是否可以告诉我我在某个特定的类/方法中,并且只在其中使用特定的日志前缀?
如果没有,有没有其他方法可以使用方法来模仿我用宏实现的行为?
答案 0 :(得分:2)
通常,您需要的Swift工具是#function
。例如:
func MyLog(msg: String, function: StaticString = #function) {
print("\(function) - \(msg)")
}
#function
,当用作默认参数值时,将计算到调用站点上的函数。由于它是默认值,因此您不必传递function
参数。
然而,这与ObjC不兼容。为此,你仍然需要宏。如果你想沿着ObjC宏转发到Swift,你会做类似的事情:
#define MYLog(message) [Log log:message function:@(__FUNCTION__)]
然后你需要以这种方式写MyLog
:
struct Log {
static func log(msg: String, function: String = #function) {
// ...
}
}
它必须位于struct
才能被ObjC访问(或者它可能是枚举),您必须使function
类型String
而不是{{1}因为ObjC无法生成StaticString
。
像这样构建,在Swift中,你会打电话:
StaticString
在ObjC中你会打电话给
Log.log("my message")
答案 1 :(得分:0)
我(通过宏扩展)产生类似的结果。
在GERuntimeConstants.h中,我定义了
extern void QuietLog(NSString *format, ...);
在GERuntimeConstants.m中,我将QuietLog提供为:
void QuietLog(NSString *format, ...) {
if (format == nil) {
printf("nil\n");
return;
}
// Get a reference to the arguments that follow the format parameter
va_list argList;
va_start(argList, format);
// Perform format string argument substitution, reinstate %% escapes, then print
NSString *s = [[NSString alloc] initWithFormat:format arguments:argList];
printf("%s\n", [[s stringByReplacingOccurrencesOfString:@"%%" withString:@"%%%%"] UTF8String]);
va_end(argList);
}
在GEMacros中,我定义了
#define __MPLOGWITHFUNCTION(s, ...) \
QuietLog(@"%s : %@",__FUNCTION__,[NSString stringWithFormat:(s), ##__VA_ARGS__])
#define MPLOG(...) __MPLOGWITHFUNCTION(__VA_ARGS__)
我在.pch中加入了GEMacros.h
我想记录的任何地方,我会有一行代码,如下例所示:
- (void)cleanupWithError:(NSString *)status message:(NSString *)message {
MPLOG(@"*** Cleaning up , status[%@], message[%@]",status,message);
并且此语句在控制台中转换为:
-[EHRCall cleanupWithError:message:] : *** Cleaning up , status[INVALID_PARAMETERS], message[No api user with api key [patient01ApiKey]]
所以在我的代码中,我使用MPLOG作为NSLog(总是)。通过_MPLOGWITHFUNCTION的定义是因为我有其他调整到构建的宏。此定义用于在调试构建时进行日志记录。对于发行版,MPLOG定义为;
。