有什么办法可以告诉我调用哪个类/方法?

时间:2016-05-18 18:10:10

标签: objective-c swift c-preprocessor

我有一个我使用的预处理器宏:

@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 方法,我可以用相同的方式调用它,并给出相同的结果。我不想管理一个对象,所以这些应该是类/静态方法。 是否可以告诉我我在某个特定的类/方法中,并且只在其中使用特定的日志前缀?

如果没有,有没有其他方法可以使用方法来模仿我用宏实现的行为?

2 个答案:

答案 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定义为;