생산 코드에 NSLog()를 사용하면 안 된다는 것이 사실입니까?
저는 이 사이트에서 이런 말을 몇 번 들었습니다. 하지만 저는 이것이 정말 사실인지 확인하고 싶었습니다.
코드 전체에 NSLog 함수 호출을 뿌릴 수 있고, 릴리스/배포 빌드를 구축할 때 Xcode/gcc가 해당 호출을 자동으로 제거할 것으로 예상했습니다.
이걸 사용하는 걸 피해야 하나요?그렇다면, 경험이 풍부한 오브젝티브-C 프로그래머들 사이에서 가장 일반적인 대안은 무엇입니까?
프리프로세서 매크로는 디버깅에 매우 유용합니다.NSLog()에는 아무런 문제가 없지만, 더 나은 기능으로 자신만의 로깅 기능을 정의하는 것은 간단합니다.여기 제가 사용하는 것이 있습니다. 파일 이름과 줄 번호가 포함되어 있어 로그 문을 쉽게 추적할 수 있습니다.
#define DEBUG_MODE
#ifdef DEBUG_MODE
#define DebugLog( s, ... ) NSLog( @"<%p %@:(%d)> %@", self, [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define DebugLog( s, ... )
#endif
저는 이 전체 문을 자체 파일보다 접두사 헤더에 넣는 것이 더 쉽다는 것을 알게 되었습니다.원하는 경우 DebugLog가 일반 Objective-C 개체와 상호 작용하도록 하여 보다 복잡한 로깅 시스템을 구축할 수 있습니다.예를 들어 자신의 로그 파일(또는 데이터베이스)에 기록하고 런타임에 설정할 수 있는 '우선 순위' 인수를 포함하는 로깅 클래스가 있을 수 있으므로 디버그 메시지는 릴리스 버전에 표시되지 않지만 오류 메시지는 표시됩니다(DebugLog(), WarningLog( 등).
하세요, 아고명심하요세리그요,.#define DEBUG_MODE응용 프로그램의 다른 위치에서 다시 사용할 수 있습니다.예를 들어 응용 프로그램에서 라이센스 키 검사를 사용하지 않도록 설정하고 특정 날짜 이전인 경우에만 응용 프로그램이 실행되도록 허용합니다.이를 통해 시간 제한이 있는 완전한 기능의 베타 복사본을 최소한의 노력으로 배포할 수 있습니다.
-prefix.pch 파일의 끝에 다음 세 줄을 놓습니다.
#ifndef DEBUG
#define NSLog(...) /* suppress NSLog when in release mode */
#endif
. 프로젝트에 정의를 내릴 필요가 없기 입니다. 왜냐하면DEBUG프로젝트를 생성할 때 기본적으로 빌드 설정에 정의됩니다.
NSLog 호출은 프로덕션 코드에 그대로 둘 수 있지만, 실제로 예외적인 경우에만 존재하거나 시스템 로그에 기록하기를 원하는 정보가 있어야 합니다.
시스템 로그를 엉망으로 만드는 애플리케이션은 성가시고 전문가답지 못한 것으로 간주됩니다.
마크 샤르보노의 답변에 대해서는 코멘트할 수 없으므로 답변으로 올려드리겠습니다.
미리 헤더에 하는 것 구성을 없음)를할 수 .DEBUG_MODE.
활성 구성 "디버깅"을 선택하면DEBUG_MODE됩니다.NSLog정의.
"해제" 활성 구성을 선택해도 정의되지 않습니다.DEBUG_MODE그리고 당신의NSLog깅이 릴리스 빌드에서 누락되었습니다.
단계:
- 대상 > 정보 얻기
- 빌드 탭
- "PreProcessor 매크로"( 또는 ) 검색
- 구성 선택:디버그
- 이 수준에서 정의 편집
- 추가
- 구성 선택:해제
- 인확을
DEBUG_MODE에 되어 있지 .GCC_PREPROCESSOR_DEFINITIONS
정의에서 '=' 문자를 생략하면 전처리기에서 오류가 발생합니다.
에 이 을 붙여 "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" ""DEBUG_MACRO를 합니다.
// Target > Get Info > Build > GCC_PREPROCESSOR_DEFINITIONS
// Configuration = Release: <empty>
// = Debug: DEBUG_MODE=1
편집: 마크 샤르보노가 게시하고 쇼를 통해 제가 주목하게 된 방법은 이것보다 훨씬 낫습니다.
디버그 모드가 비활성화되었을 때 빈 함수를 사용하여 로깅을 비활성화할 것을 제안한 답변 부분을 삭제했습니다.자동 전처리기 매크로 설정을 다루는 부분은 여전히 관련이 있으므로 그대로 유지됩니다.저는 또한 프리프로세서 매크로의 이름을 마크 샤르보노의 답변과 더 잘 일치하도록 편집했습니다.
Xcode에서 자동(및 예상) 동작을 수행하려면:
프로젝트 설정에서 "빌드" 탭으로 이동하여 "디버그" 구성을 선택합니다. 매크로 후 "Preprocessor 매로섹"라는 합니다.DEBUG_MODE.
...
편집: 로그를 활성화하거나 비활성화하는 올바른 방법은 Marc Charbonneau의 답변을 참조하십시오.DEBUG_MODE거시적인
저는 매튜의 말에 동의합니다.NSLog는 생산 코드에 이상이 없습니다.사실, 그것은 사용자에게 유용할 수 있습니다.즉, NSLog를 사용하는 유일한 이유가 디버그를 돕기 위한 것이라면 릴리스하기 전에 제거해야 합니다.
게다가, 당신이 이것을 아이폰 질문으로 태그했기 때문에, NSLog는 아이폰이 거의 가지고 있지 않은 귀중한 자원을 가져갑니다.NS가 iPhone에 기록하는 경우 앱의 프로세서 시간이 줄어듭니다.현명하게 사용하세요.
간단한 사실은 NSLog가 매우 느리다는 것입니다.
하지만 왜 그랬을까?이 질문에 답하기 위해 NSLog가 수행하는 작업과 수행 방법에 대해 알아보겠습니다.
NSLog는 정확히 무엇을 합니까?
NSLog는 두 가지 작업을 수행합니다.
로그 메시지를 Apple System Logging(asl) 기능에 기록합니다.이렇게 하면 로그 메시지가 Console.app에 표시됩니다.또한 응용 프로그램의 stderr 스트림이 터미널로 가는지 확인합니다(예: 응용 프로그램이 Xcode를 통해 실행되는 경우).이 경우 로그 메시지를 stderr에 기록합니다(Xcode 콘솔에 표시됨).
STDERR에 글을 쓰는 것은 어렵지 않게 들립니다.이 작업은 fprintf와 stderr 파일 설명자 참조를 통해 수행할 수 있습니다.하지만 sl은?
제가 ASL에 대해 찾은 최고의 문서는 Peter Hosey의 10부 블로그 게시물입니다.
세부적으로 설명하지 않아도 성능과 관련된 주요 내용은 다음과 같습니다.
ASL 기능에 로그 메시지를 보내려면 기본적으로 ASL 데몬에 대한 클라이언트 연결을 열고 메시지를 보냅니다.그러나 - 각 스레드는 별도의 클라이언트 연결을 사용해야 합니다.따라서 스레드 안전을 위해 NSLog가 호출될 때마다 새 asl 클라이언트 연결을 열고 메시지를 보낸 다음 연결을 닫습니다.
다른 답변에서 언급한 것처럼 #define을 사용하여 컴파일 시 NSLog 사용 여부를 변경할 수 있습니다.
그러나 보다 유연한 방법은 실행 시에도 무언가가 기록되는지 여부를 변경할 수 있는 Cocoa Lumberjack과 같은 로깅 라이브러리를 사용하는 것입니다.
코드에서 NSLog를 DDLogVerbose 또는 DDLogError 등으로 대체하고 매크로 정의 등에 대한 #import를 추가한 다음 applicationDidFinishLaunching 메서드에서 로거를 설정합니다.
NSLog와 동일한 효과를 얻기 위해 구성 코드는 다음과 같습니다.
[DDLog addLogger:[DDASLLogger sharedInstance]];
[DDLog addLogger:[DDTTYLogger sharedInstance]];
보안 측면에서는 기록되는 내용에 따라 다릅니다.한다면NSLog(또는 다른 로거)가 중요한 정보를 작성하고 있으므로 프로덕션 코드에서 로거를 제거해야 합니다.
감사의 관점에서 감사자는 각 용도를 보고 싶어하지 않습니다.NSLog중요한 정보를 기록하지 않도록 합니다.그/그녀는 단순히 로거를 제거하라고 말할 것입니다.
저는 두 그룹 모두에서 일합니다.우리는 코드 감사, 코딩 가이드 작성 등을 합니다.본 가이드에서는 생산 코드에서 로깅을 사용할 수 없도록 설정해야 합니다.그래서 내부 팀들은 그것을 시도하지 않는 것을 알고 있습니다 ;)
또한 중요한 정보를 실수로 유출하는 것과 관련된 위험을 감수하고 싶지 않기 때문에 운영 환경에 로그인하는 외부 앱도 거부합니다.우리는 개발자가 우리에게 뭐라고 말하든 상관하지 않습니다.조사할 시간이 없습니다.
그리고 우리는 개발자가 아닌 '민감한' 것을 정의합니다 ;)
저는 또한 많은 로깅을 수행하는 앱을 붕괴할 준비가 된 앱으로 인식합니다.많은 로깅이 수행/필요하지만 일반적으로 안정성이 떨어지는 이유가 있습니다.바로 위에 '감시자' 스레드가 있어 중단된 서비스를 다시 시작합니다.
보안 아키텍처(SecArch) 검토를 한 번도 경험해 본 적이 없는 경우 다음과 같이 살펴봅니다.
릴리스 코드에서 NSLog에 대한 인쇄를 불필요하게 장황하게 해서는 안 됩니다.NSLog에 대한 인쇄는 앱에 잘못된 오류, 즉 복구할 수 없는 오류가 발생한 경우에만 시도하십시오.
NSLogs는 UI/메인 스레드의 속도를 늦출 수 있습니다.꼭 필요한 경우가 아니면 릴리스 빌드에서 제거하는 것이 가장 좋습니다.
로깅(무료)을 위해 TestFlight를 사용하는 것을 강력히 추천합니다.이 메서드는 NSLog(매크로 사용)를 재정의하고 NSLog에 대한 기존의 모든 호출에 대해 해당 서버, Apple System 로그 및 STDERR 로그에 대한 로깅을 설정/해제할 수 있습니다.좋은 점은 사용자의 시스템 로그에 로그가 표시되지 않고도 테스터에 배포된 앱과 앱스토어에 배포된 앱에 대한 로그 메시지를 검토할 수 있다는 것입니다.두 세계의 장점.
언급URL : https://stackoverflow.com/questions/300673/is-it-true-that-one-should-not-use-nslog-on-production-code
'programing' 카테고리의 다른 글
| 잠시 동안 루프에서 tqdm 진행 표시줄 사용 (0) | 2023.05.21 |
|---|---|
| 시트를 삭제하고 대신 사용자 지정 메시지를 사용하여 Excel이 사용자에게 확인을 요청하지 않도록 합니다. (0) | 2023.05.21 |
| 기본값 유형이 속성 유형과 일치하지 않습니다. (0) | 2023.05.21 |
| Windows에서 원격/대상 리포지토리 URL을 변경하려면 어떻게 해야 합니까? (0) | 2023.05.16 |
| 비동기 방식으로 코드를 디버깅할 수 없는 이유는 무엇입니까? (0) | 2023.05.16 |