在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 "" case .fatal: return "" case .none: return "" } } } public static var minimumLogLevel: logLevel = .info public static func print(_ object: T, _ level: logLevel = .debug, filename: String = #file, line: Int = #line, funcname: String = #function) { if level.rawValue >= Stuff.minimumLogLevel.rawValue { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MM/dd/yyyy HH:mm:ss:SSS" let process = ProcessInfo.processInfo let threadId = "?" let file = URL(string: filename)?.lastPathComponent ?? "" Swift.print("\n\(level.description()) .\(level) ? \(dateFormatter.string(from: Foundation.Date())) \(process.processName) [\(process.processIdentifier):\(threadId)] \(file)(\(line)) ?? \(funcname) ??\r\t\(object)") } } }
您可以这样使用:
Stuff.print("Just as the standard print but now with detailed information") Stuff.print("Now it's a warning", .warn) Stuff.print("Or even an error", .error) Stuff.minimumLogLevel = .error Stuff.print("Now you won't see normal log output") Stuff.print("Only errors are shown", .error) Stuff.minimumLogLevel = .none Stuff.print("Or if it's disabled you won't see any log", .error)
这将导致:
?? .debug ? 02/13/2017 09:52:51:852 xctest [18960:?] PrintStuffTests.swift(15) ?? testExample() ?? Just as the standard print but now with detailed information ?? .warn ? 02/13/2017 09:52:51:855 xctest [18960:?] PrintStuffTests.swift(16) ?? testExample() ?? Now it's a warning .error ? 02/13/2017 09:52:51:855 xctest [18960:?] PrintStuffTests.swift(17) ?? testExample() ?? Or even an error .error ? 02/13/2017 09:52:51:855 xctest [18960:?] PrintStuffTests.swift(21) ?? testExample() ?? Only errors are shown
Kreiri.. 94
斯威夫特有#file
,#function
,#line
和 #column
.来自Swift编程语言:
#file
- String - 出现的文件的名称.
#line
- Int - 出现的行号.
#column
- Int - 开始的列号.
#function
- String - 出现的声明的名称.
从XCode beta 6开始,您可以使用reflect(self).summary
获取类名并__FUNCTION__
获取函数名称,但现在情况有点严重.希望他们能提出更好的解决方案.在我们退出测试版之前使用#define可能是值得的.
这段代码:
NSLog("[%@ %@]", reflect(self).summary, __FUNCTION__)
给出这样的结果:
2014-08-24 08:46:26.606 SwiftLessons[427:16981938] [C12SwiftLessons24HelloWorldViewController (has 2 children) goodbyeActiongoodbyeAction]
编辑:这是更多的代码,但让我更接近我需要的东西,我认为这是你想要的.
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__) }
它提供如下输出:
2014-08-24 09:52:12.159 SwiftLessons[1397:17145716] app: SwiftLessons class: ViewController func: flowAction
斯威夫特有#file
,#function
,#line
和 #column
.来自Swift编程语言:
#file
- String - 出现的文件的名称.
#line
- Int - 出现的行号.
#column
- Int - 开始的列号.
#function
- String - 出现的声明的名称.
我更喜欢定义全局日志功能:
[Swift 3.1]
func ZYLog(_ object: Any?, filename: String = #file, line: Int = #line, funcname: String = #function) { #if DEBUG print("****\(Date()) \(filename)(\(line)) \(funcname):\r\(object ?? "nil")\n") #endif }
[Swift 3.0]
func ZYLog<T>(_ object: T?, filename: String = #file, line: Int = #line, funcname: String = #function) { #if DEBUG print("****\(Date()) \(filename)(\(line)) \(funcname):\r\(object)\n") #endif }
[Swift 2.0]
func ZYLog<T>(object: T, filename: String = __FILE__, line: Int = __LINE__, funcname: String = __FUNCTION__) { println("****\(filename.lastPathComponent)(\(line)) \(funcname):\r\(object)\n") }
输出是这样的:
****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"; }
Swift 4
这是我的方法:
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()
额外:您将看到线程被执行,[T]表示后台线程,[M]表示主线程.
这是一个更新的Swift 2答案.
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)]" }
使用示例:
LogW("Socket connection error: \(error)")
从Swift 2.2开始我们应该使用:
#file(String)显示它的文件的名称.
#line(Int)出现的行号.
#column(Int)开始的列号.
#function(String)出现的声明的名称.
来自Swift编程语言(Swift 3.1),第894页.
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