답변:
주장은 가치가 예상대로 이루어 지도록하는 것입니다. 어설 션이 실패하면 문제가 발생하여 앱이 종료 된 것입니다. assert를 사용하는 한 가지 이유는 전달 된 매개 변수 중 하나가 정확히 일부 값 (또는 값 범위)이 아닌 경우 동작하지 않거나 매우 나쁜 부작용을 일으키는 기능이있는 경우 만들 수 있습니다. 가치가 당신이 기대하는 값인지 확인하십시오. 그렇지 않으면 뭔가 잘못되어 앱이 종료됩니다. Assert는 디버깅 / 단위 테스트 및 사용자가 "악한"일을하지 않도록하는 프레임 워크를 제공 할 때 매우 유용 할 수 있습니다.
NSAssert와 실제로 대화 할 수는 없지만 C의 assert ()와 유사하게 작동한다고 생각합니다.
assert ()는 코드에서 시맨틱 계약을 시행하는 데 사용됩니다. 그게 무슨 소리 야?
자, 당신이 말한 것과 같습니다 : -1을 절대로받지 않아야하는 함수가 있다면 assert ()가 다음을 시행하도록 할 수 있습니다.
void gimme_positive_ints (int i) { 주장 (i> 0); }
이제 오류 로그 (또는 STDERR)에 다음과 같은 내용이 표시됩니다.
어설 션 i> 0 실패 : 파일 example.c, 2 행
따라서 잠재적으로 잘못된 입력을 방지 할뿐만 아니라 유용한 표준 방식으로 기록합니다.
그리고 적어도 C에서는 assert ()가 매크로이므로 릴리스 코드에서 assert ()를 no-op로 다시 정의 할 수 있습니다. NSAssert (또는 더 이상 assert ())의 경우인지는 모르겠지만 해당 검사를 컴파일하는 것이 매우 유용했습니다.
NSAssert
앱을 다운시키는 것 이상을 제공합니다. 클래스, 메소드 및 어설 션이 발생한 행을 알려줍니다. NS_BLOCK_ASSERTIONS를 사용하여 모든 어설 션을 쉽게 비활성화 할 수 있습니다. 따라서 디버깅에 더 적합합니다. 반면에 던지면 NSException
앱이 충돌합니다. 또한 예외의 위치에 대해서는 알려주지 않으며 간단하게 비활성화 할 수 없습니다. 아래 이미지의 차이점을 참조하십시오.
NSAssert 설명서에 설명 된 대로 어설 션에서도 예외가 발생하므로 앱이 중단 됩니다.
호출되면 어설 션 핸들러는 메소드 및 클래스 이름 (또는 함수 이름)을 포함하는 오류 메시지를 인쇄합니다. 그런 다음 NSInternalInconsistencyException 예외가 발생합니다.
NSAssert :
NSException :
NSException
그것이를 통해 반환 출력 사용자 정의 할 수 많은 기회 제공 reason
및 userInfo
매개 변수를. 클래스 이름, 선택기, 줄 정보 및 디버깅을 돕기 위해 추가해야 할 항목을 추가 할 수 없었습니다. IMHO는 NSAssert
개발 중에 디버깅 목적으로 를 사용 하지만 배송을 비활성화합니다. NSException
운송 코드에 명제를 남기고 싶다면를 던집니다 .
누군가가 언급했지만 완전히 설명하지 않은 것처럼 명확히하기 위해 사용자 정의 코드를 작성하는 대신 어설 션을 사용하고 사용하는 이유는 (예를 들어 if를 수행하고 잘못된 데이터에 대한 예외를 발생시키는) 프로덕션 애플리케이션에 대해 어설 션을 비활성화해야한다는 것입니다.
개발 및 디버깅 중에 오류를 포착 할 수있는 어설 션이 활성화됩니다. 어설 션이 false로 평가되면 프로그램이 중지됩니다. 그러나 프로덕션을 위해 컴파일 할 때 컴파일러는 어설 션 코드를 생략하고 실제로 프로그램 실행 속도를 높입니다. 그때까지 모든 버그를 수정했으면합니다. 생산 중에 프로그램에 여전히 버그가있는 경우 (어설 션이 비활성화되고 프로그램이 어설 션을 "스킵"하는 경우) 프로그램이 다른 지점에서 중단 될 수 있습니다.
NSAssert의 도움말에서 : "전 처리기 매크로 NS_BLOCK_ASSERTIONS가 정의되면 어설 션이 비활성화됩니다." 따라서 배포 대상에 매크로를 넣으면됩니다.
NSAssert
(및 그 stdlib에 상응하는 assert
)는 개발 중 프로그래밍 오류를 감지하는 것입니다. 프로덕션 (릴리스 된) 응용 프로그램에서 실패한 어설 션이 없어야합니다. 따라서 양의 인수가 필요한 메소드에 음수를 전달하지 않도록 주장 할 수 있습니다. 테스트 중에 어설 션이 실패하면 버그가있는 것입니다. 그러나 전달 된 값이 사용자에 의해 입력 된 경우 프로덕션의 어설 션에 의존하지 않고 입력에 대한 올바른 유효성 검사를 수행해야합니다 (비활성화 된 릴리스 빌드에 대해 #define을 설정할 수 있음) NSAssert*
.
어설 션 프로그래밍은 런타임 검사 외에도 계약으로 코드를 설계 할 때 사용되는 중요한 기능이라는 점을 지적하는 것이 좋습니다.
계약에 의한 주장 및 설계 주제에 대한 자세한 정보는 아래에서 확인할 수 있습니다.
그의 질문에 완전히 대답하기 위해 어떤 종류의 주장이든 디버깅을 돕는 것입니다. 소스에서 오류를 포착 한 다음 충돌을 일으킬 때 디버거에서 오류를 포착하는 것이 더 중요합니다.
예를 들어, 특정 범위의 값을 기대하는 함수에 값을 전달할 수 있습니다. 이 함수는 나중에 사용하기 위해 값을 저장하고 나중에 사용하면 응용 프로그램이 중단됩니다. 이 시나리오에서 볼 수있는 호출 스택에는 잘못된 값의 소스가 표시되지 않습니다. 누가 나쁜 가치를 전달하는지와 그 이유를 알아 내기 위해 나쁜 가치를 포착하는 것이 좋습니다.
NSAssert
조건과 일치하면 앱이 충돌합니다. 조건과 일치하지 않으면 다음 명령문이 실행됩니다. 아래 EX를 찾으십시오.
방금 작업이 무엇인지 테스트하는 앱을 만듭니다 NSAssert
.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self testingFunction:2];
}
-(void)testingFunction: (int)anNum{
// if anNum < 2 -> the app will crash
// and the NSLog statement will not execute
// that mean you cannot see the string: "This statement will execute when anNum < 2"
// into the log console window of Xcode
NSAssert(anNum >= 2, @"number you enter less than 2");
// If anNum >= 2 -> the app will not crash and the below
// statement will execute
NSLog(@"This statement will execute when anNum < 2");
}
내 코드에 앱이 충돌하지 않으며 테스트 사례는 다음과 같습니다.
anNum
> = 2-> 앱이 중단되지 않고 다음 로그 문자열을 볼 수 있습니다. "이 명령문은 outPut 로그 콘솔 창에"Num <2 "일 때 실행됩니다.anNum
<2-> 앱이 중단되고 다음과 같은 로그 문자열을 볼 수 없습니다 : "이 명령문은 anNum <2"