是否有NSLog的Swift替代方案(@“%s”,__ PRETTY_FUNCTION__)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否有NSLog的Swift替代方案(@“%s”,__ PRETTY_FUNCTION__)相关的知识,希望对你有一定的参考价值。

在Objective C中,您可以使用以下命令记录正在调用的方法:

NSLog(@"%s", __PRETTY_FUNCTION__)

通常,这是从日志记录宏中使用的。

虽然Swift不支持宏(我认为),但我仍然希望使用包含被调用函数名称的通用日志语句。在Swift中可以吗?

更新:我现在使用此全局函数进行日志记录,可在此处找到:https://github.com/evermeer/Stuff#print您可以使用以下命令安装:

pod 'Stuff/Print'

这是代码:

public class Stuff {

    public enum logLevel: Int {
        case info = 1
        case debug = 2
        case warn = 3
        case error = 4
        case fatal = 5
        case none = 6

        public func description() -> String {
            switch self {
            case .info:
                return "❓"
            case .debug:
                return "✳️"
            case .warn:
                return "⚠️"
            case .error:
                return "
答案

斯威夫特有#file#function#line#column。来自Swift Programming Language

#file - String - 出现的文件的名称。

qazxsw poi - In - 出现的行号。

qazxsw poi - In - 开始的列号。

#line - String - 出现的声明的名称。

另一答案

Swift 3.x +

如果您不想要整个文件名,那么这里有一个快速解决方法。

import UIKit

func logFunctionName(file:NSString = __FILE__, fnc:String = __FUNCTION__){  
    println("(file.lastPathComponent):(fnc)")
}
另一答案

记录函数调用的另一种方法:

public func LogFunction<T>(object: T, filename: String = #file, line: Int = #line, funcname: String = #function) {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss:SSS"
    let process = ProcessInfo.processInfo()
    let threadId = "?"
    print("(dateFormatter.string(from:Date())) (process.processName) [(process.processIdentifier):(threadId)] (filename)((line)) (funcname)::: (object)")
}
另一答案

从Swift 2.2开始我们应该使用:

  • #file(String)显示它的文件的名称。
  • #line(In)出现的行号。
  • #column(In)开始的列号。
  • #function(String)出现的声明的名称。

来自#column,第894页。

#function
另一答案

斯威夫特4 这是我的方法:

The Swift Programming Language (Swift 3.1)

使这成为一个全局函数,只需调用

func specialLiterals() {
    print("#file literal from file: (#file)")
    print("#function literal from function: (#function)")
    print("#line: (#line) -> #column: (#column)")
}
// Output:
// #file literal from file: My.playground
// #function literal from function: specialLiterals()
// #line: 10 -> #column: 42

额外:您将看到线程被执行,[T]表示后台线程,[M]表示主线程。

另一答案

从XCode beta 6开始,你可以使用func pretty_function(_ file: String = #file, function: String = #function, line: Int = #line) { let fileString: NSString = NSString(string: file) if Thread.isMainThread { print("file:(fileString.lastPathComponent) function:(function) line:(line) [M]") } else { print("file:(fileString.lastPathComponent) function:(function) line:(line) [T]") } } 来获取类名,使用pretty_function() 来获取函数名,但是现在有些东西已经被破坏了。希望他们能提出更好的解决方案。在我们退出测试版之前使用#define可能是值得的。

这段代码:

reflect(self).summary

给出这样的结果:

__FUNCTION__

编辑:这是更多的代码,但让我更接近我需要的东西,我认为这是你想要的。

NSLog("[%@ %@]", reflect(self).summary, __FUNCTION__)

它提供如下输出:

2014-08-24 08:46:26.606 SwiftLessons[427:16981938] [C12SwiftLessons24HelloWorldViewController (has 2 children) goodbyeActiongoodbyeAction]
另一答案

我更喜欢定义全局日志功能:

[Swift 3.1]

func intFromString(str: String) -> Int
{
    var result = 0;
    for chr in str.unicodeScalars
    {
        if (chr.isDigit())
        {
            let value = chr - "0";
            result *= 10;
            result += value;
        }
        else
        {
            break;
        }
    }

    return result;
}


@IBAction func flowAction(AnyObject)
{
    let cname = _stdlib_getTypeName(self)
    var parse = cname.substringFromIndex(1)                                 // strip off the "C"
    var count = self.intFromString(parse)
    var countStr = String(format: "%d", count)                              // get the number at the beginning
    parse = parse.substringFromIndex(countStr.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
    let appName = parse.substringToIndex(count)                             // pull the app name

    parse = parse.substringFromIndex(count);                                // now get the class name
    count = self.intFromString(parse)
    countStr = String(format: "%d", count)
    parse = parse.substringFromIndex(countStr.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
    let className = parse.substringToIndex(count)
    NSLog("app: %@ class: %@ func: %@", appName, className, __FUNCTION__)
}

[Swift 3.0]

2014-08-24 09:52:12.159 SwiftLessons[1397:17145716] app: SwiftLessons class: ViewController func: flowAction

[Swift 2.0]

func ZYLog(_ object: Any?, filename: String = #file, line: Int = #line, funcname: String = #function) {
    #if DEBUG
    print("****(Date()) (filename)((line)) (funcname):
(object ?? "nil")
")
    #endif
}

输出是这样的:

func ZYLog<T>(_ object: T?, filename: String = #file, line: Int = #line, funcname: String = #function) {
    #if DEBUG
    print("****(Date()) (filename)((line)) (funcname):
(object)
")
    #endif
}
另一答案

这是一个更新的Swift 2答案。

func ZYLog<T>(object: T, filename: String = __FILE__, line: Int = __LINE__, funcname: String = __FUNCTION__) {
    println("****(filename.lastPathComponent)((line)) (funcname):
(object)
")
}

使用示例:

****ZYHttpSessionManager.swift(78) POST(_:parameters:success:failure:):
[POST] user/login, {
    "auth_key" = xxx;
    "auth_type" = 0;
    pwd = xxx;
    user = "xxx";
}

****PointViewController.swift(162) loadData():
review/list [limit: 30, skip: 0]

****ZYHttpSessionManager.swift(66) GET(_:parameters:success:failure:):
[GET] review/list, {
    "auth_key" = xxx;
    uuid = "xxx";
}
另一答案

或者轻微的功能修改:

func LogW(msg:String, function: String = __FUNCTION__, file: String = __FILE__, line: Int = __LINE__){
    print("[WARNING](makeTag(function, file: file, line: line)) : (msg)")
}

private func makeTag(function: String, file: String, line: Int) -> String{
    let url = NSURL(fileURLWithPath: file)
    let className:String! = url.lastPathComponent == nil ? file: url.lastPathComponent!
    return "(className) (function)[(line)]"
}

}

/ *将产生一个执行跟踪,如:AppDelegate:application(_:didFinishLaunchingWithOptions :):18产品:init(类型:名称:年份:价格:):34 FirstViewController:viewDidLoad():15 AppDelegate:applicationDidBecomeActive:62 * /

另一答案

我使用,这是swift文件中所需的全部内容,所有其他文件都会将其拾取(作为全局函数)。当您想要发布应用程序时,只需注释掉该行。

LogW("Socket connection error: (error)")
另一答案

Swift 3.0

func logFunctionName(file:String = __FILE__, fnc:String = __FUNCTION__, line:(Int)=__LINE__) {
    var className = file.lastPathComponent.componentsSeparatedByString(".")
    println("(className[0]):(fnc):(line)")

以上是关于是否有NSLog的Swift替代方案(@“%s”,__ PRETTY_FUNCTION__)的主要内容,如果未能解决你的问题,请参考以下文章

swift NSLog的Swift替代品

Swift:摆脱时间戳 NSLog()

在 Swift 项目中为生产禁用 NSLog

Flex 框架的替代方案

performSelectorOnMainThread 的 Swift 替代方案

radiansToVector 和 randomInRange Objective-C 函数的 Swift 替代方案是啥? [关闭]