릴리스 버전 iOS Swift에 대한 println () 제거


84

println()디버그 빌드가 아닌 경우 Swift 코드의 모든 호출 을 전역 적으로 무시하고 싶습니다 . 이에 대한 단계별 지침을 찾을 수 없으며 지침에 감사드립니다. 전 세계적으로이 작업을 수행하거나 할 내가 모든 서라운드해야 할 수있는 방법이 println()함께 #IF DEBUG/#ENDIF문은?



6
print는 더 이상 장치 콘솔에서 출력되지 않지만 디버거 콘솔에서 수행됩니다. 따라서 릴리스 버전을 위해 제거 할 필요가 없습니다.
Anish Parajuli 웃

1
Xcode 8 및 swift 3부터 릴리스 모드의 콘솔에 인쇄물이 표시되지 않습니다.
CiNN

답변:


101

가장 간단한 방법은 Swift의 앞에 자신 만의 전역 함수를 배치하는 것입니다 println.

func println(object: Any) {
    Swift.println(object)
}

로깅을 중지 할 때가되면 해당 함수의 본문을 주석 처리하십시오.

func println(object: Any) {
    // Swift.println(object)
}

또는 조건부를 사용하여 자동으로 만들 수 있습니다.

func println(object: Any) {
    #if DEBUG
        Swift.println(object)
    #endif
}

EDIT Swift 2.0 println에서 print. 불행히도 이제 가변적 인 첫 번째 매개 변수가 있습니다. 이것은 멋지지만 Swift에는 "splat"연산자가 없기 때문에 쉽게 재정의 할 수 없으므로 코드에서 variadic을 전달할 수 없습니다 (문자 그대로 만 생성 할 수 있음). 그러나 일반적으로 그렇듯이 하나의 값만 인쇄하는 경우 작동하는 축소 버전을 만들 수 있습니다.

func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

Swift 3에서는 첫 번째 매개 변수의 외부 레이블을 억제해야합니다.

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    Swift.print(items[0], separator:separator, terminator: terminator)
}

3
감사합니다. iOS (OS X 제외)에서는 println()릴리스 모드에서 실행 되지 않는다고 들었습니다 .
Nate Birkholz 2015 년

13
@NateBirkholz 아니, 그건 말도 안돼. (그는 확인하기 위해 테스트 한 후 말했다!)
matt

스위프트 2에서 함수 이름이 print로 변경된 상태에서 func가 일치 할 가능성이 있습니까? 또한 이것을 전역 적으로 어떻게 정의 하시겠습니까? 나는 그것을 AppDelegate의 클래스 외부에 두려고 시도했지만 백만 번의 print () 호출이 있어도 호출되지 않았습니다. 내가 시도한 것은 다음과 같습니다. func print (object : Any) {Swift.print (object)}
Charlie

예 @Charlie, 나는 아직도 그것을 사용하고 있습니다 println로 변경 print. 그것이 작동하지 않는 이유는 print정의가 Swift와 일치하지 않으므로 재정의하지 않기 때문입니다. 여러 번 언급했듯이 Swift에는 splat 연산자가 없으므로 variadic을 전달할 수 없기 때문에 약간의 문제가 있습니다. 그러나 하나의 항목에 대해 잘 작동하며 items[0].
matt

2
이러한 로그 문을 코드의 고성능 섹션에 삽입하는 경우 한 가지주의 사항 : Swift는 사용되지 않더라도 함수에 전달하기 위해 문자열 보간 및 렌더링 매개 변수를 수행하는 데 시간을 소비합니다. 명령문을 실제로 조건부로 제거하는 유일한 방법은 플래그에 조건부를 지정하는 것입니다. 예를 들어, 사용되는 각 위치에서 if (log) {print (..)}.
Pat Niemeyer 2015

46

Swift 4.x 업데이트 :

이제 Swift 2.0 / 3.0 및 Xcode 7/8이 베타 버전으로 출시되면서 릴리스 빌드에서 인쇄 기능을 비활성화하는 방법에 몇 가지 변경 사항이 있습니다.

위의 @matt 및 @Nate Birkholz가 언급 한 몇 가지 중요한 사항이 여전히 유효합니다.

  1. println()함수로 대체 한print()

  2. #if DEBUG 매크로 를 사용하려면 값을 포함하도록 "Swift Compiler-Custom Flags -Other Flags"를 정의해야합니다.-D DEBUG

  3. 코드에서 정상적으로 함수를 Swift.print()사용할 수 있도록 전역 범위에서 함수를 재정의하는 것이 좋지만 print()디버그가 아닌 빌드의 출력은 제거됩니다. 다음은 Swift 2.0 / 3.0에서이를 수행하기 위해 전역 범위에 추가 할 수있는 함수 서명입니다.

    func print(items: Any..., separator: String = " ", terminator: String = "\n") {
    
        #if DEBUG
    
        var idx = items.startIndex
        let endIdx = items.endIndex
    
        repeat {
            Swift.print(items[idx], separator: separator, terminator: idx == (endIdx - 1) ? terminator : separator)
            idx += 1
        }
        while idx < endIdx
    
        #endif
    }
    

참고 : 여기서는 기본 구분 기호를 공백으로 설정하고 기본 종결자는 줄 바꾸기로 설정했습니다. 원하는 경우 프로젝트에서 다르게 구성 할 수 있습니다.

도움이 되었기를 바랍니다.

최신 정보:

일반적으로이 함수를 전역 범위에 두는 것이 바람직하므로 Swift의 print함수 앞에 위치 합니다. 이를 구성하는 가장 좋은 방법은이 함수를 전역 범위에 배치 할 수있는 프로젝트 (예 : DebugOptions.Swift)에 유틸리티 파일을 추가하는 것입니다.

Swift 3부터 ++연산자는 더 이상 사용되지 않습니다. 이 변경 사항을 반영하기 위해 위의 스 니펫을 업데이트했습니다.


1
죄송합니다. 기능을 어디에 넣을까요?
DàChún 2015 년

@ User9527 아마도 프로젝트 전체에서 액세스 할 수 있도록 전역 범위의 어딘가에 배치하고 싶을 것입니다. 내 프로젝트에서 유틸리티 스위프트 파일 (DebugOptions.swift 또는 이와 유사한 것)을 추가하고이 함수를 전역 범위 (즉, 동봉 된 클래스가 아닌)에 배치합니다.
Glavid 2015

현재 버전의 Swift-Xcode에서 확인할 수 있습니까? -D Debug flat을 설정할 필요없이 print 문이 더 이상 장치 콘솔에 출력되지 않습니다. 적어도 그것이 내가 오늘 시험 한 것입니다.
user523234 2010

1
"... (인쇄 _ 항목"스위프트 3로, 하나는 인수 목록의 시작 부분에 밑줄을 추가하여 좀 더 간결를 얻을 수 있습니다
조나단 ZHAN

7
그래서 나는 (didFinishLaunching ...에서 사용 된) 프린트의 참조를 찾아 보았고 그것은 나를 원래의 프린트 함수 인 Swift를 가리 켰습니다. 그것과 @JonathanZhan의 코멘트를 합쳐서, 나는 다음과 같이 보이도록 기능을 조정했고 그것이 작동합니다 :public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
Jonny

38

저를 포함하여 이러한 모든 접근 방식의 문제점은 print인수 평가의 오버 헤드를 제거하지 않는다는 것 입니다. 어떤 것을 사용하든 비용이 많이 듭니다.

print(myExpensiveFunction())

유일한 해결책은 조건부 컴파일에서 실제 인쇄 호출을 래핑하는 DEBUG것입니다 (디버그 빌드에만 정의되어 있다고 가정합시다 ).

#if DEBUG
print(myExpensiveFunction())
#endif

그리고 그것만이 myExpensiveFunction릴리스 빌드에서 호출되는 것을 방지 합니다.

그러나 autoclosure 를 사용하여 평가를 한 단계 뒤로 밀어 낼 수 있습니다 . 따라서 다음과 같이 내 솔루션 (이것은 Swift 3)을 다시 작성할 수 있습니다.

func print(_ item: @autoclosure () -> Any, separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    Swift.print(item(), separator: separator, terminator: terminator)
    #endif
}

이것은 일반적으로 사실 인 한 가지만 인쇄하는 경우에만 문제를 해결합니다. item()릴리스 모드에서 호출되지 않기 때문 입니다. print(myExpensiveFunction())따라서 호출이 평가되지 않고 클로저로 래핑되고 릴리스 모드에서는 전혀 평가되지 않기 때문에 비용이 많이 들지 않습니다.


무엇을 사용 @autoclosure합니까?
킬린

책에서 @matt에 "인쇄의 중요한 기능은 앱이 Xcode와 독립적으로 실행될 때 효과적으로 표시되지 않는다는 것입니다."라고 언급했습니다. 이는 최근 제출 된 앱에 인쇄 명세서를 남길 수 있다는 의미입니까, 아니면 제가 오해하고있는 것입니까? 어떤 것?
hidden-username

@ hidden-username 예, print배송 코드에 명세서 를 남기는 경향이 있지만 여기에있는 제 답변과는 다릅니다. print문 출력은 엑스 코드에 독립적 인 릴리즈 빌드에서 콘솔로 전송되지 않습니다 있지만 아직 평가 가 비싼 또는 원치 않는 부작용이 단지의 경우 그 평가를 억제하는 방법을 알고 도움이 유지되도록.
matt

@matt oh ok ... 네, 오해했습니다. 주석 처리하겠습니다. 감사합니다
hidden-username

이 방법은 바이너리 파일에서 인쇄 된 문자열을 제거합니까? 예를 들어 내가 그 방법을 사용하고 내 앱의 어딘가에 "print ("user login in ")"를 넣은 다음 누군가 내 앱을 리버스 엔지니어링하려고하면 어딘가에서이 문자열을 찾게 될까요, 아니면 전혀 없을까요?
Leszek Szary 19 dec

18

언급했듯이, 저는 학생이고 따라하기 위해 좀 더 명확하게 정의 된 것이 필요합니다. 많은 연구 끝에 따라야 할 순서는 다음과 같습니다.

Xcode 프로젝트 창 왼쪽의 파일 탐색기 상단에있는 프로젝트 이름을 클릭합니다. 프로젝트 이름, 빌드 대상 수 및 iOS SDK 버전이있는 행입니다.

Build Settings 탭을 선택하고 하단 근처 에있는 " Swift Compiler-Custom Flags "섹션으로 스크롤하십시오 . 섹션을 확장하려면 기타 플래그 옆에있는 아래쪽 화살표를 클릭합니다 .

디버그 라인을 클릭 하여 선택하십시오. 선의 오른쪽에 마우스 커서를 놓고 두 번 클릭합니다. 목록보기가 나타납니다. 값을 추가하려면 목록보기의 왼쪽 하단에 있는 + 버튼을 클릭합니다 . 텍스트 필드가 활성화됩니다.

텍스트 필드에 텍스트를 입력하고 Return 키-D DEBUG눌러 행을 커밋합니다.

프로젝트에 새 Swift 파일을 추가하십시오. 파일에 대한 사용자 정의 클래스를 만들려고하므로 다음 행을 따라 텍스트를 입력하십시오.

class Log {

  var intFor : Int

  init() {
    intFor = 42
   }

  func DLog(message: String, function: String = __FUNCTION__) {
    #if DEBUG
      println("\(function): \(message)")
    #endif
  }
}

오늘 Xcode에서 클래스를 수락하는 데 문제가 있었기 때문에 init가 필요 이상으로 더 무거울 수 있습니다.

이제 println()적용 가능한 모든 클래스의 속성 으로 Add this 대신 새 사용자 지정 함수를 사용하려는 모든 클래스에서 사용자 지정 클래스를 참조해야합니다 .

   let logFor = Log()

이제의 모든 인스턴스 println()logFor.DLog(). 출력에는 행이 호출 된 함수의 이름도 포함됩니다.

클래스 함수 내에서 해당 클래스의 클래스 함수로 함수의 복사본을 만들지 않는 한 함수를 호출 할 수 없으며 println()입력이 좀 더 유연하므로 모든 인스턴스에서 사용할 수 없습니다. 내 코드.


8
디버그 로그에 대한 사용자 지정 클래스를 만들 필요가 없습니다. 전역 함수를 사용하는 것이 더 쉽고 실용적입니다.
Vojtech Vrbka 2015

intFor = 42의 용도는 무엇입니까?
Ted

15

스위프트 5

프로젝트에서 새 파일을 만들고 다음 코드를 붙여 넣기 만하면됩니다.

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)        
    }
    #endif
}

이 함수 서명은 기본 Swift 서명과 일치하므로 프로젝트의 함수를 "덮어 씁니다". 필요한 경우을 사용하여 원본에 계속 액세스 할 수 있습니다 Swift.print().

위의 코드를 추가 한 후에 print()는 평소와 같이 계속 사용 하면 디버그 빌드에서만 인쇄됩니다.

참고 : forEach각 항목을 인쇄하기 위해을 수행하면 바로으로 전달하는 경우 표시되는 인쇄 문 주위의 성가신 배열 대괄호가 제거 items됩니다 Swift.print().

Swift를 처음 접하는 사람이라면 도대체 무엇인지 궁금 할 것 $0입니다. forEach블록에 전달 된 첫 번째 인수를 나타냅니다 . forEach문은 다음과 같이 작성할 수 있습니다 :

items.forEach { item in
    Swift.print(item, separator: separator, terminator: terminator)        
}

마지막으로 관심이 있다면 Swift 선언은 print다음과 같습니다.

public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")

위의 대답은 정확한 Swift 구현을 반영합니다.하지만 한 가지 이상을 인쇄하거나 구분 기호 / 종료자를 변경하지 않습니다. 그러나 누가 알겠습니까?


2
이 함수를 선언 할 곳, 이것은 이와 같은 확장 또는 smth입니까? 난 그냥) 각 파일에 선언하고 싶지 않아
Matrosov 알렉산더에게

1
@MatrosovAlexander 앱 프로젝트의 어느 곳에서나 신속한 파일을 생성하고이 코드를 넣을 수 있습니다. 컴파일러는 전 세계적으로 액세스 할 수있을만큼 똑똑합니다.
Trev14

11

내가 사용하는 함수는 Swift 3에서 완벽하게 작동합니다.

func gLog<T>( _ object: @autoclosure() -> T, _ file: String = #file, _ function: String = #function, _ line: Int = #line)
    {
    #if DEBUG
        let value = object()
        let stringRepresentation: String

        if let value = value as? CustomDebugStringConvertible
            {
            stringRepresentation = value.debugDescription
            }
        else if let value = value as? CustomStringConvertible
            {
            stringRepresentation = value.description
            }
        else
            {
            fatalError("gLog only works for values that conform to CustomDebugStringConvertible or CustomStringConvertible")
            }

        let fileURL = NSURL(string: file)?.lastPathComponent ?? "Unknown file"
        let queue = Thread.isMainThread ? "UI" : "BG"
    let gFormatter = DateFormatter()
    gFormatter.dateFormat = "HH:mm:ss:SSS"
        let timestamp = gFormatter.string(from: Date())

        print("✅ \(timestamp) {\(queue)} \(fileURL) > \(function)[\(line)]: " + stringRepresentation + "\n")
    #endif
    }

다음은 생성되는 출력의 예입니다.

출력 스크린 샷

설명:

  • 녹색 확인 표시는 콘솔에서 인쇄 (gLog) 메시지를 빠르게 볼 수 있도록하는 데 사용됩니다.이 메시지는 때때로 다른 메시지의 바다에서 손실 될 수 있습니다.

  • 시간 / 날짜 스탬프

  • 실행중인 스레드-제 경우에는 MainThread (UI라고 부름)이거나 MainThread (백그라운드 스레드의 경우 BG라고 함)가 아닙니다.

  • gLog 메시지가있는 파일의 이름

  • gLog 메시지가있는 파일 내의 기능

  • gLog 메시지의 줄 번호

  • 인쇄하려는 실제 gLog 메시지

이것이 다른 사람에게 유용하기를 바랍니다!


이 파일을 별도의 파일에 넣어 앱 전체에서 모두 사용할 수 있습니까? 클래스 메서드로 별도의 클래스 파일에 넣어 보았습니다. 하지만 libMobileGestalt MobileGestaltSupport.m : 153과 충돌합니다. pid 2574 (데모)는 frZQaeyWLUvLjeuEK43hmg에 대한 샌드 박스 액세스 권한이 없으며 libMobileGestalt MobileGestalt.c : 550 : InverseDeviceID에 대한 액세스 권한이 없습니다 (<rdar : // problem / 11744455> 참조). ) 디버거의 메시지 : 메모리 문제로 인해 종료 됨
omarojo

omarojo, 나는 이것을 내 앱 전체에서 전역 함수로 사용합니다. 수업이 필요하지 않습니다. 이와 같은 모든 유틸리티 함수를 포함하는 utils.swift라는 파일이 있습니다. Foundation을 가져 오기만하면됩니다. 아마도 그게 당신이 놓친 단계일까요? 그건 그렇고, 클래스 내에서 정적 함수 또는 전역 함수로 함수를 선언하는 방법에 대한 자세한 내용은 다음 SO 질문 및 답변을 참조하십시오. stackoverflow.com/questions/30197548/…
Gene Loparco

네, 내부에 함수가있는 새 파일을 만들어서 작동합니다. 어떤 이유로 클래스 함수로 사용하면 명확한 디버그 메시지없이 앱이 충돌합니다.
omarojo

이 사람에게 감사합니다. 이전에 발견하지 못했던 수치입니다. 많은 디버깅 문제를 해결했습니다.
beowulf

내 기쁨 @beowulf!
Gene Loparco

9

Swift 2.1Xcode 7.1.1로 테스트 됨

Swift 컴파일러에 의해 빈 함수가 제거 되었다는 사실을 알고 나면 릴리스 버전에서 모든 print 문을 제외하는 쉬운 방법이 있습니다 .

사이드 노트 : 오브젝티브 C의 시대에, 내 대답에 설명 된 것처럼 컴파일러에서 쫓겨 전에 NSLog 문을 제거하는 데 사용할 수있는 사전 파서 있었다 여기가 . 그러나 Swift에는 더 이상 pre-parser가 없기 때문에이 접근법은 더 이상 유효하지 않습니다.

릴리스 빌드에서 제거하는 것에 대해 걱정할 필요없이 오늘 내가 고급 및 쉽게 구성 가능한 로그 기능으로 사용하는 것은 다음과 같습니다. 또한 다른 컴파일러 플래그를 설정하여 필요에 따라 기록되는 정보를 조정할 수 있습니다.

필요에 따라 기능을 조정할 수 있으며 개선을위한 제안을 환영합니다!

// Gobal log() function
//
// note that empty functions are removed by the Swift compiler -> use #if $endif to enclose all the code inside the log()
// these log() statements therefore do not need to be removed in the release build !
//
// to enable logging
//
// Project -> Build Settings -> Swift Compiler - Custom flags -> Other Swift flags -> Debug
// add one of these 3 possible combinations :
//
//      -D kLOG_ENABLE
//      -D kLOG_ENABLE -D kLOG_DETAILS
//      -D kLOG_ENABLE -D kLOG_DETAILS -D kLOG_THREADS
//
// you can just call log() anywhere in the code, or add a message like log("hello")
//
func log(message: String = "", filePath: String = #file, line: Int = #line, function: String = #function) {
            #if kLOG_ENABLE

            #if kLOG_DETAILS

            var threadName = ""
            #if kLOG_THREADS
                threadName = NSThread.currentThread().isMainThread ? "MAIN THREAD" : (NSThread.currentThread().name ?? "UNKNOWN THREAD")
                threadName = "[" + threadName + "] "
            #endif

            let fileName = NSURL(fileURLWithPath: filePath).URLByDeletingPathExtension?.lastPathComponent ?? "???"

            var msg = ""
            if message != "" {
                msg = " - \(message)"
            }

            NSLog("-- " + threadName + fileName + "(\(line))" + " -> " + function + msg)
        #else
            NSLog(message)
        #endif
    #endif
}

다음은 컴파일러 플래그를 설정하는 곳입니다.

여기에 이미지 설명 입력

모든 플래그가있는 예제 출력은 다음과 같습니다.

   2016-01-13 23:48:38.026 FoodTracker[48735:4147607] -- [MAIN THREAD] ViewController(19) -> viewDidLoad() - hello

log ()가있는 코드는 다음과 같습니다.

    override func viewDidLoad() { log("hello")
    super.viewDidLoad()

   // Handle the text field's user input through delegate callbacks
   nameTextField.delegate = self
}

잘 했어! 여기서 가져 와서 결국 AELogAEConsole을 만들었습니다 .
tadija

이것은 DEBUG 모드에서 잘 작동합니다. 이제 Edit Scheme에서 RELEASE 모드로 변경했습니다. 릴리스 모드에 대한 로그인 콘솔 창도 표시됩니다. 왜 그렇습니까?
Jayprakash Dubey

Xcode 9의 Swift 3.2의 경우 log (message : "hello")를 사용하여 인쇄하고 호출하도록 NSLog를 변경해야했습니다. 또한 따옴표와 함께 "-D" "kLOG_ENABLE"로 플래그를 넣어야했습니다. 다른 모든 빠른 버전 업데이트는 제안 된 수정 사항과 함께 컴파일러에 의해 선택되었습니다.
iCyberPaul

1
여기에서 "빈 함수는 Swift 컴파일러에 의해 제거됩니다"라고 말합니다. 문서에서 그것을 찾을 수있는 곳은 어디입니까? 그게 사실인지 어떻게 압니까? @ ronny-webers
zumzum

7

디버그 빌드 설정 -D DEBUG이 설정 되었는지 확인한 후 더 간단합니다 OTHER_SWIFT_FLAGS.

#if !DEBUG
    func print(_ items: Any..., separator: String = " ", terminator: String = "\n") { }
#endif

wwdc에 대한 vids에서 드물게 언급 된 시스템 프로토콜 중 하나를 따르기 때문에 인쇄 가능한 개체가 "where"가 필요할 수 있다고 생각합니다. 빠른 가이드가 끝날 때 1.2 대 2에서 차이를 잊어 버렸습니다. 시스템 1과 하나입니다
Stephen J

지금까지 이것은 Swift 1.2에서 작동합니다. 2.0을 시도하지 않았습니다.
Rivera

6

XCode 8은 몇 가지 새로운 빌드 설정을 도입했습니다 .
특히 언급 된 Active Compilation Conditions것은 기타 플래그 설정 과 유사한 방식으로 수행됩니다.

"활성 컴파일 조건"은 조건부 컴파일 플래그를 Swift 컴파일러에 전달하기위한 새로운 빌드 설정입니다.

XCode 8 (8.2.2에서 테스트 됨)에 따라 기본적으로 다음과 같이 표시됩니다.

여기에 이미지 설명 입력

따라서 구성없이 다음을 작성할 수 있습니다.

#if DEBUG
    print("⚠️ Something weird happened")
#endif

이 접근 방식을 광범위하게 사용하는 경우이 로깅 논리를 래핑하는 클래스 / 구조 / 함수를 만드는 것이 좋습니다. 이것을 길 아래로 더 확장 할 수 있습니다.


4

Varun Naharia는 지금까지 더 나은 솔루션을 가지고 있습니다. 나는 그의 대답을 Rivera의 ...

  1. 크리에이트 -D DEBUG컴파일러 지시어, 빌드 설정에 플래그.
  2. 그런 다음 다음 코드를 추가하십시오.

    #if !DEBUG
     public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    }
    #endif
    

이 코드는 print릴리스를 위해 모든 것을 아무것도 변환 하지 않습니다.


3

스위프트 4 Xcode 10.0

아마도 이것을 사용할 수 있습니다

func dPrint(_ message: @autoclosure () -> Any) {
    #if DEBUG
    print(message())
    #endif
}

사용하는 이유는 @autoclosure메시지 매개 변수로 함수를 전달하면 함수가 디버그 모드에서만 호출되어 성능 저하가 발생하기 때문입니다.

Swift.print(_ items: Any..., separator: String = default, terminator: String = default)함수 와 달리 내 솔루션에는 매개 변수가 하나만 있습니다. 대부분의 경우 인쇄 함수가 콘솔에 정보 만 표시하므로 여러 매개 변수를 전달하지 않기 때문에 매개 변수를 String :으로 변환 할 수 있습니다 "\(param1)"+"\(param2)". 내 솔루션을 좋아하길 바래


1

중단 점을 사용하고 평가 후 계속하도록 설정하고 중단 점에 인쇄 메시지를 쓸 수도 있습니다!

여기에 이미지 설명 입력


0

debug_println대략적인 내용을 정의 할 수 있습니다.

#if DEBUG
  println()
#endif

감사합니다. 어디에서 가장 잘 정의 할 수 있습니까? 저는 학생입니다. 두렵고 도움을 주셔서 감사하지만 좀 더 명확한 맥락이 필요합니다.
Nate Birkholz 2014

사용하려는 모든 위치로 가져올 헤더 파일에서 선언합니다.
Ian MacDonald

0

내 솔루션은 클래스 전에 AppDelegate 에서이 코드를 사용합니다.

// Disable console log in live app
#if !arch(x86_64) && !arch(i386)
    public func debugPrint(items: Any..., separator: String = " ", terminator: String = "\n") {

    }
    public func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {

    }
#endif

class AppDelegate: UIResponder, UIApplicationDelegate {
// App Delegate Code 

}

0

내 솔루션을 위해 간단하게 만듭니다.

import UIKit

class DLog: NSObject {

   init(title:String, log:Any) {
       #if DEBUG
           print(title, log)
       #endif

   }

}

그런 다음 그것을 보여주기 위해

_ = DLog(title:"any title", log:Any)

0

나는 이것을 사용하여 결국 :

#if DEBUG
func dLog(_ item: @autoclosure () -> Any, _ file: String = #file, _ function: String = #function, _ line: Int = #line) {
    print("\(Date()) [\((file as NSString).lastPathComponent):\(line) \(function)] \(item())")
}
#else
func dLog(_ item: @autoclosure () -> Any) {}
#endif

매우 간결하고 유용한 정보 (타임 스탬프, 빠른 파일 이름, 코드 줄, 함수 이름)를 인쇄하고 적어도 내 테스트에서 16 진수 편집기에서 열 때 응용 프로그램 바이너리 파일에서 로깅 된 문자열을 찾을 수 없습니다.


0

더 간단하게 : 어설 션이 릴리스 빌드에서 제거되고 거기에서만 인쇄를 호출한다는 사실을 활용하십시오. 릴리스를 위해 빌드 할 때 비어 있으므로 모든 로그 호출 (예, Log.da에 대한 호출 포함) 이 제거 됩니다 .

그러나 릴리스 빌드에서 인쇄물이 제거되었다고 들었지만 서면으로 찾을 수 없었습니다. 그래서 지금은 Log아래와 같은 것을 사용하고 있습니다. 이모 지 (가독성을 위해)와 로그 주제 (일관성을 위해)가있는 GitHub에 더 많은 버전이 있습니다.

https://github.com/Gatada/JBits/blob/master/Project/Utility/Log.swift

public enum Log {

    /// A date formatter used to create the timestamp in the log.
    ///
    /// This formatter is only created if it is actually used, reducing the
    /// overhead to zero.
    static var formatter: DateFormatter?

    // MARK: - API

    /// Call to print message in debug area.
    ///
    /// Asserts are removed in release builds, which make
    /// the function body empty, which caused all calls to
    /// be removed as well.
    ///
    /// Result is zero overhead for release builds.
    public static func da(_ message: String) {
        assert(debugAreaPrint(message))
    }

    // MARK: - Helpers

    /// The function that actually does the printing. It returns `true` to
    /// prevent the assert from kicking in on debug builds.
    private static func debugAreaPrint(_ message: String) -> Bool {
        print("\(timestamp) - \(message)")
        return true
    }

    /// Creates a timestamp used as part of the temporary logging in the debug area.
    static private var timestamp: String {

        if formatter == nil {
            formatter = DateFormatter()
            formatter!.dateFormat = "HH:mm:ss.SSS"
        }

        let date = Date()
        return formatter!.string(from: date)
    }
}

코드에서 :

Log.da("This is only handled in a debug build.")

디버그 빌드를 실행할 때만 Xcode 디버그 영역에 표시 됩니다 .

13 : 36 : 15.047-이것은 디버그 빌드에서만 처리됩니다.


0

내 프로젝트는 Objective C로 개발되었지만 작년부터 Swift에서 새 코드를 병합하기 시작했습니다. 그래서 Swift 아래 솔루션에서 저에게 효과가 있었으므로 해당 코드를 My Swift 상수 파일에 추가했습니다.

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
    items.forEach {
        Swift.print($0, separator: separator, terminator: terminator)
    }
    #endif
}

0

이것은 나를 위해 작동합니다 (프로젝트의 전역 기능으로 추가하십시오)

func print(_ items: Any...) {
    #if DEBUG
        Swift.print(items[0])
    #endif
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.