Objective-C에서 null 문자열을 확인하는 올바른 방법은 무엇입니까?


184

내 아이폰 앱에서 이것을 사용하고 있었다

if (title == nil) {
    // do something
}

그러나 예외가 발생하고 콘솔에 제목이 "(null)"이라는 메시지가 표시됩니다.

그래서 나는 이것을 지금 사용하고 있습니다 :

if (title == nil || [title isKindOfClass:[NSNull class]]) {
    //do something
}

차이점은 무엇이며 문자열이 null인지 확인하는 가장 좋은 방법은 무엇입니까?


답변:


395

다른 사람들이 지적했듯이 Cocoa / Objective C에는 많은 종류의 "null"이 있습니다. 그러나 주목해야 할 또 하나의 점은 [title isKindOfClass : [NSNull class]]는 [NSNull null]이 싱글 톤이므로 포인터 평등을 확인할 수 있습니다. 코코아 주제 : Null 사용을 참조하십시오 .

따라서 좋은 테스트는 다음과 같습니다.

if (title == (id)[NSNull null] || title.length == 0 ) title = @"Something";

title이 nil 인 경우에도 title.length는 0 / nil / false, 즉이 경우 0을 반환하므로 특별한 경우가 필요하지 않습니다. 이것은 Objective C를 처음 사용하는 사람들이 익숙해 지는데 어려움을 겪었습니다. 특히 메시지 / 메소드 호출이 충돌하지 않는 다른 언어에서 발생합니다.


감사! 그러나 "title"이 null이기 때문에 예외가 발생했기 때문에 처음 에이 질문을했습니다.
Teo Choong Ping

1
제목은 어떤 유형입니까? 예를 들어 NSString 인 경우 다음과 같은 경고가 나타납니다. 개별 Objective-C 유형 'struct NSNull *'와 'struct NSString *'에 캐스트가 없습니다.이를 제거 할 수있는 방법이 있습니까? 이 질문을 받았습니다)?
thebossman

1
컴파일하지 않고 코드를 게시 할 권리가 있습니다. ;-). title은 아마도 NSString이지만 title의 유형에 관계없이 일반 id 유형으로 null을 캐스트합니다. (id) [NSNull null].
피터 N 루이스

1
@JLT nil과 [NSNull null]은 동일하지 않습니다. [NSNull null]은 nil을 사용할 수없는 경우 (예 : NSArray 또는 NSDictionary 값) nil의 스탠드로 사용할 수있는 싱글 톤 객체입니다. 따라서 유스 케이스는 선택적 문자열의 NSArray를 가진 곳일 수 있으며, 일부는 널일 수 있으며 널 케이스의 경우 배열에서 [NSNull null]을 사용합니다. 실제로 테스트는 거의 필요하지 않습니다. 사용자 (또는 사용하는 라이브러리!)가 [NSNull null]을 자리 표시 자로 적극적으로 사용하는 경우에만 가능합니다.
Peter N Lewis

1
플러터에서 이곳으로오고, 그리고 이유를 찾고 Map항목의 값 -이다 null다트에이 -에 해당하지 않는 nil또는 NULL이유는 그것이 실제로이었다 목적 C.에 NUNull null의하지 NULL줍니다. 감사합니다 @PeterNLewis!
Aleksandar

25

그것은만큼 간단합니다

if([object length] >0)
{
  // do something
}

목적 C에서 object가 null이면 0을 값으로 반환한다는 것을 기억하십시오.

이렇게하면 null 문자열과 0 길이 문자열을 모두 얻을 수 있습니다.


49
객체가 NSNull 인 경우 작동하지 않으므로 먼저 명시 적으로 확인해야합니다.
Jeremy Mack

6
당신은 또한 길이 메시지에 0을 반환하도록 NSNull의 카테고리를 만들 수 있습니다 :)
Mihai Timar

1
예, 객체가 NSNull이면 충돌이 발생합니다.
Mike Gledhill 2016 년

객체가 NSNull과 같은 경우 충돌이 발생합니다.
joan

1
NSNull 인식 할 수없는 선택기 문제 외에, 이것은 nil 인 NSString 포인터 또는 실제로 존재하지만 본질적으로 빈 문자열 인 NSString을 구별하지 않습니다. (예 : 리터럴 object = @"";또는 object = nil;)
KellyTheDude

6

이 사이트에서 다음 관련 기사를 참조하십시오.

추가 검사를 할 필요가 없으므로 오류가 다른 것과 관련이 있다고 생각합니다.

이 관련 질문도 참조하십시오 : nil sqlite 텍스트 열의 적절한 검사


성가 시게 나는 (심지어이 사이트에 뭔가에) 두 번째 하이퍼 링크를 추가하기에 충분한 "포인트"가없는 항목 : - stackoverflow.com/questions/598396/...
TIMM

...저를 허용. 담당자 0에서 자신의 게시물을 편집 할 수 있어야합니다.
Rog

고마워-그것은 매우 친절했다. 초기 게시물을 썼을 때 새로운 사용자와 같은 것은 하이퍼 링크를 1 개만 추가 할 수 있다고 말했습니다 (특히이 사이트의 크로스 링크의 경우 약간 거칠어 보입니다).
TimM 2016 년

6

나는 실제로 그것을 올바르게하기 위해서는 비슷한 것을해야한다는 것을 알았습니다.

if ( ( ![myString isEqual:[NSNull null]] ) && ( [myString length] != 0 ) ) {
}

그렇지 않으면 제어가 여전히 검사를 우회하는 이상한 상황이 발생합니다. 나는 isEqual길이 검사를 통과 한 것을 보지 못했습니다 .


5

이 "어떻게 대답 해"? 우리는 모두 같은 언어로 코딩하고 규칙은

  1. 참조가 0 이 아닌지 확인
  2. 문자열 길이가 0이 아닌지 확인하고 확인하십시오.

그것이 모두에게 효과가있는 것입니다. 지정된 솔루션 만 "작동"하는 경우 응용 프로그램 흐름에서 참조가 null이거나 문자열 길이가 0 일 수있는 시나리오를 허용하지 않기 때문입니다.이를 수행하는 올바른 방법은 처리 할 방법입니다. 모든 경우에 원하는 것.


4
참조가 nil(참고 : "null"이 아닌 경우 )와 같은 메시지를 보내면 length0 (또는 메소드의 리턴 유형에 적절한 0 값)이 생성됩니다. 이것이 언어의 규칙입니다. nil이 경우 별도로 확인할 필요가 없습니다 .
jscs

나는 단순히 C ++ 습관으로 인해 null을 말했으며 코드가 nil 객체에서 메소드를 호출하면 코드가 손상되었을 가능성이 있습니다. NULL / NIL (동일한 개념)에서 메소드를 호출하는 것은 일반적으로 모든 언어에서 나쁜 생각입니다. obj-c를 사용하면 이와 같은 일을 할 수 있다고해서 nil 객체를 전달하고 신경 쓰지 않고 사용하려고한다는 의미는 아닙니다.
nenchev 2016 년

1
길이를 nil로 전송하면 0이 생성되지만 NSNull로 길이를 전송하면 예외가 발생합니다.
cdstamper

@nenchev 아무도 nil 객체를 전달하는 것에 대해 아무 말도하지 않지만 nil을 확인한 다음 메소드를 호출하고 반환 값을 사용하는 것은 사용되는 언어 기능을 사용하고 나중에 메소드의 반환 값의 유효성을 확인하는 것보다 IMO가 나쁩니다.
Kevin

@Kevin 언어 기능이 그다지 큰 의미가 아니기 때문에 실제로 얼마나 나쁜지 잘 모르겠습니다. null이 코드 경로를 열어 런타임 오류 추적이 더 어려울 수 있는지 확인하지 않습니다. 일반적으로 입력이 예상 한대로 확인하고 입력이 적절하지 않은 경우 적절하게 반응하는 것이 가장 좋습니다. 필자는 nil 객체에 메시지를 보내려고 할 때 런타임 예외가 발생하지 않는 "기능"을 개인적으로 좋아하지 않습니다. 종종 런타임 버그를 놓치기가 더 쉽기 때문입니다.
nenchev

4

빈 문자열이나 빈 배열 / 세트와 같은 모든 nil / empty 객체에 대해 테스트하려면 다음을 사용할 수 있습니다.

static inline BOOL IsEmpty(id object) {
    return object == nil
        || ([object respondsToSelector:@selector(length)]
        && [(NSData *) object length] == 0)
        || ([object respondsToSelector:@selector(count)]
        && [(NSArray *) object count] == 0);
}

2
이것은 실제로 의미가있는 객체 == [NSNull null]을 확인하지 않습니다.
Peter N Lewis

3

두 가지 상황이 있습니다.

객체가 [NSNull null]이거나 불가능할 수 있습니다.
응용 프로그램은 일반적으로 [NSNull null];" null "객체를 배열에 넣거나 사전 값으로 사용 하려는 경우에만 사용 해서는 안됩니다 . 그런 다음 어떤 배열이나 사전에 null 값이 포함될 수 있고 그렇지 않을 수 있는지 알아야합니다.
배열에 [NSNull null]값이 포함되어 있지 않다고 생각되면 확인하지 마십시오. 이 있으면 [NSNull null]예외가 발생하지만 괜찮습니다. Objective-C 예외는 프로그래밍 오류를 나타냅니다. 그리고 일부 코드를 변경하여 수정해야하는 프로그래밍 오류가 있습니다.

객체 있다면 [NSNull null]테스트를 통해 간단히 확인할 있습니다
(object == [NSNull null]). isEqual객체의 클래스를 호출 하거나 확인하는 것은 말이되지 않습니다. 단 하나의 [NSNull null]객체가 있으며 평범한 오래된 C 연산자는 가장 간단하고 효율적인 방식으로 잘 검사합니다.

당신이 선택하면 NSString될 수 없다 객체 [NSNull null]당신이 될 수 없습니다 알고 있기 때문에 ( [NSNull null]또는 그냥 다른 것을 선택하기 때문에를 [NSNull null], 당신은 당신이 만약 길이가 0이 하나 인 빈 문자열을 치료하는 방법을 스스로에게 물어 필요 그것은이다 치료 null와 같은 문자열 nil, 다음 테스트 (object.length == 0). 경우 object.length는 0을 반환합니다 object == nil길이가 0과 객체와 문자열 전무이 테스트 커버 당신이 전무 문자열에서 다른 길이 0의 문자열을 취급한다면, 단지 경우 확인 object == nil.

마지막으로 배열이나 사전에 문자열을 추가하고 문자열이 nil 인 경우 문자열을 추가하지 @""않거나으로 바꾸거나으로 바꿀 수 있습니다 [NSNull null]. 이를 바꾸면 @"""문자열 없음"과 "길이가 0 인 문자열"을 구별 할 수 없게됩니다. 이를 대체한다는 것은 객체 [NSNull null]를 검사하는 배열이나 사전에 액세스 할 때 코드를 작성해야 함을 의미 [NSNull null]합니다.


매우 길지만 이것은 좋습니다. NSNull은 한 번만 나타나야합니다! 이 모든 질문은 이해가되지 않으며, 코더가 올바른 일을하지 않았으며 앞으로 더 많은 사람들이 수동 / 좋은 코드 연습을 읽지 않았다고 말합니다.
Stephen J

2

당신은 단지 nil을 확인

if(data[@"Bonds"]==nil){
  NSLog(@"it is nil");
}

또는

if ([data[@"Bonds"] isKindOfClass:[NSNull class]]) {
    NSLog(@"it is null");
}

2

매크로 솔루션 (2020)

예를 들어 UILabel 에서 " (null) "문자열을 얻는 대신 안전한 문자열에 사용하는 매크로는 다음과 같습니다 .

#define SafeString(STRING) ([STRING length] == 0 ? @"" : STRING)

멤버 클래스와 이름 속성이 있고 이름이 nil이라고 가정 해 봅시다.

NSLog(@"%@", member.name); // prints (null) on UILabel

매크로로 :

NSLog(@"%@", SafeString(member.name)); // prints empty string on UILabel

좋고 깨끗한 😊

확장 솔루션 (2020)

프로젝트에서 nil Null 및 빈 문자열을 확인하려면 아래 확장 줄을 사용할 수 있습니다.

NSString + Extension.h

///
/// Checks if giving String is an empty string or a nil object or a Null.
/// @param string string value to check.
///
+ (BOOL)isNullOrEmpty:(NSString*)string;

NSString + Extension.m

+ (BOOL)isNullOrEmpty:(NSString*)string {
    if (string) { // is not Nil
        NSRange range = [string rangeOfString:string];
        BOOL isEmpty = (range.length <= 0 || [string isEqualToString:@" "]);
        BOOL isNull = string == (id)[NSNull null];

        return (isNull || isEmpty);
    }

    return YES;
}

사용법 예

if (![NSString isNullOrEmpty:someTitle]) {
    // You can safely use on a Label or even add in an Array for example. Remember: Arrays don't like the nil values!
}



1
@interface NSString (StringFunctions)
- (BOOL) hasCharacters;
@end

@implementation NSString (StringFunctions)
- (BOOL) hasCharacters {
    if(self == (id)[NSNull null]) {
        return NO;
    }else {
        if([self length] == 0) {
            return NO;
        }
    }
    return YES;
}
@end

NSString *strOne = nil;
if([strOne hasCharacters]) {
    NSLog(@"%@",strOne);
}else {
    NSLog(@"String is Empty");
}

다음과 같은 경우 NSString *strOne = @""OR NSString *strOne = @"StackOverflow"OR NSString *strOne = [NSNull null]OR에서 작동 NSString *strOne합니다.


0

그런 종류의 것이 존재하지 않으면 NSString 범주를 만들 수 있습니다.

@interface NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty;

@end

@implementation NSString (TrucBiduleChoseAdditions)

- (BOOL)isEmpty {
    return self == nil || [@"" isEqualToString:self];
}

@end

아마 과잉 일 것이며이 문제를 해결할 것이라고 생각하지 않습니다.
Rog

9
self == nil은 의미가 없습니다. self가 nil이면 Objective C가 처음에 전화하지 않았을 것입니다. [(NSString *) nil isEmpty]는 코드를 호출하지 않고 단순히 0 / nil / false를 반환합니다.
Peter N Lewis

4
실제로 [(NSString *) nil isEmpty]는 false를 반환합니다. 이러한 Objective C 메소드를 작성할 때 nil의 0 / nil / false가 의미가 있도록 메소드를 정의하는 것이 좋으므로 hasCharacters로 메소드를 작성하는 것이 좋습니다. if (! s.isEmpty) 및 s.length는 s == nil 경우 0을 올바르게 반환 할 경우 if (s.length)를 사용할 수 있기 때문에 length는 이미이 작업에 적용됩니다.
Peter N Lewis

이것은 심각한 충돌입니다. NSString에 대해 "isEmpty"를 구현했지만 실제로 NSNull 인 경우 isEmpty가 NSNull로 전송되고 해당 메시지에 응답하지 않기 때문에 충돌이 발생합니다!
daniel.gindi

0

나를 위해 일하는 것은 if ( !myobject )


3
null 객체에는 작동하지 않으며 nil 객체에만 작동합니다. 예를 들어 ... NSArray *testarray = [NSArray arrayWithObjects:[NSNull null],@"", nil]; NSString *string = [testarray objectAtIndex:0]; NSLog(@"null string value: %@",string); if (!string) { NSLog(@"string evaluates to null"); } if (string && (string==(id)[NSNull null])) { NSLog(@"string does not evaluate to null"); }
Rik Smith-Unna

Err .. 형식에 대해 죄송하지만 코드는 컴파일됩니다 :)
Rik Smith-Unna

0

null 조건에 대한 문자열 확인은 다음과 같습니다. <\ br>

    if (mystring)
     {
       if ([mystring isEqualToString : @ ""])
        {
          mystring = @ "일부 문자열";
        }
     }    
    그밖에
     {
        // 문명
     }

0

나는 null 문자열 만 검사합니다.

if ([myString isEqual : [NSNull null]])


0
if ([linkedStr isEqual:(id)[NSNull null]])
                {
                    _linkedinLbl.text=@"No";
                }else{
                    _linkedinLbl.text=@"Yes";
                }

1
이 코드 스 니펫은 질문에 대답 할 수 있지만 방법과 이유를 설명하는 컨텍스트를 제공하지는 않습니다. 답을 설명하기 위해 한두 문장을 추가하십시오.
brandonscript

0
if ([strpass isEqual:[NSNull null]] || strpass==nil || [strpass isEqualToString:@"<null>"] || [strpass isEqualToString:@"(null)"] || strpass.length==0 || [strpass isEqualToString:@""])
{
    //string is blank  
}

0

문자열의 경우 :

+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
if (string == nil || string.length == 0) return NO;
return YES;

}

아래 그림을 참조하십시오.

여기에 이미지 설명을 입력하십시오


0

문자열의 경우 :

+ (BOOL) checkStringIsNotEmpty:(NSString*)string {
if (string == nil || string.length == 0) return NO;
return YES;}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.