programing

Nullable, __nullable 및 _Nullable in Objective-C의 Nullable의 차이

subpage 2023. 4. 14. 21:41
반응형

Nullable, __nullable 및 _Nullable in Objective-C의 Nullable의 차이

Xcode 6.3에서는 Objective-C에서 API의 의도를 더 잘 표현하기 위해(물론 Swift 지원을 더 잘하기 위해) 새로운 주석이 도입되었습니다.그 주석들은 물론nonnull,nullable ★★★★★★★★★★★★★★★★★」null_unspecified.

그러나 Xcode 7에서는 다음과 같은 경고가 많이 나타납니다.

포인터에 nullability 형식 지정자(_Nonnull, _Nullable 또는 _Null_unspecified)가 없습니다.

이와 더불어 Apple은 다른 유형의 nullability 지정자를 사용하여 C 코드(소스)를 표시합니다.

CFArrayRef __nonnull CFArrayCreate(
CFAllocatorRef __nullable allocator, const void * __nonnull * __nullable values, CFIndex numValues, const CFArrayCallBacks * __nullable callBacks);

요약하면 다음과 같은 3가지 nullability 주석이 있습니다.

  • nonnull,nullable,null_unspecified
  • _Nonnull,_Nullable,_Null_unspecified
  • __nonnull,__nullable,__null_unspecified

어떤 주석을 사용해야 하는 이유와 장소는 알 수 있지만, 어떤 유형의 주석을 사용해야 하는지, 어디에 사용해야 하는지, 왜 사용해야 하는지 약간 헷갈립니다.내가 알 수 있는 건 이거야

  • 에 대해서는, 「 」를 합니다.nonnull,nullable,null_unspecified.
  • 는 '마음의 매개 변수'를합니다.nonnull,nullable,null_unspecified.
  • 은 C로 .__nonnull,__nullable,__null_unspecified.
  • 에 예를 들어 더블 같은 제가 '더블 포인터'를 사용하는 이 좋습니다._Nonnull,_Nullable,_Null_unspecified.

하지만 왜 이렇게 많은 주석이 기본적으로 동일한 기능을 하는지 아직도 잘 모르겠습니다.

제 질문은 다음과 같습니다.

이러한 주석의 정확한 차이, 올바른 배치 방법 및 이유는 무엇입니까?

clang 문서:

수 있는지 여부를 나타냅니다(nullability(type))._Nullable('는 되어 있지 _Nonnull(''null')_Null_unspecified무효무효 수식자보다 입니다.nonnull ★★★★★★★★★★★★★★★★★」returns_nonnull 이외의 포인터 늘 한 포인터를 들어 수 .Nullability 한정자는 해당 한정자가 적용되는 포인터의 오른쪽에 쓰여집니다.

,그리고.

Objective-C에는 컨텍스트에 민감한 언더스코어 없는 키워드를 사용하여 Objective-C 메서드 및 속성에서 사용할 수 있는 nullability 수식자의 대체 철자가 있습니다.

메서드 및 인 " double-under-cored versions 。__nonnull/__nullable/__null_unspecified단열식이나 비열열식 대신 말이죠차이점은 단일 밑줄과 이중 밑줄은 유형 정의 뒤에 배치해야 하며, 밑줄이 없는 것은 유형 정의 앞에 배치해야 한다는 것입니다.

따라서 다음 선언은 동일하며 올바른 선언입니다.

- (nullable NSNumber *)result
- (NSNumber * __nullable)result
- (NSNumber * _Nullable)result

파라미터의 경우:

- (void)doSomethingWithString:(nullable NSString *)str
- (void)doSomethingWithString:(NSString * _Nullable)str
- (void)doSomethingWithString:(NSString * __nullable)str

속성:

@property(nullable) NSNumber *status
@property NSNumber *__nullable status
@property NSNumber * _Nullable status

이중 포인터나 블록이 void와 다른 것을 반환하는 경우, 언더스코어 이외의 포인터는 사용할 수 없기 때문에 복잡합니다.

- (void)compute:(NSError *  _Nullable * _Nullable)error
- (void)compute:(NSError *  __nullable * _Null_unspecified)error;
// and all other combinations

로, 「」는 「」로 있습니다.nonnull/nullable한정자는 반환 유형이 아닌 블록에 적용됩니다.을 사용하다

- (void)executeWithCompletion:(nullable void (^)())handler
- (void)executeWithCompletion:(void (^ _Nullable)())handler
- (void)executeWithCompletion:(void (^ __nullable)())handler

블록에 반환값이 있는 경우 다음 중 하나의 언더스코어 버전이 강제로 적용됩니다.

- (void)convertObject:(nullable id __nonnull (^)(nullable id obj))handler
- (void)convertObject:(id __nonnull (^ _Nullable)())handler
- (void)convertObject:(id _Nonnull (^ __nullable)())handler
// the method accepts a nullable block that returns a nonnull value
// there are some more combinations here, you get the idea

결론적으로 컴파일러가 한정자를 할당하는 항목을 결정할 수 있는 한, 어느쪽이든 사용할 수 있습니다.

Swift 블로그에서:

이 기능은 __nullable 및 __nonnull 키워드를 사용하여 Xcode 6.3에서 처음 출시되었습니다.서드파티 라이브러리와의 잠재적인 충돌로 인해 Xcode 7에서는 _Nullable 및 Nonnull로 변경되었습니다.그러나 Xcode 6.3과의 호환성을 위해 매크로 __nullable 및 _nonnull을 정의하여 새 이름으로 확장합니다.

clang 매뉴얼에서 다음 순서를 수행합니다.

nullability(유형) 한정자는 지정된 포인터 유형의 값이 null일 수 있는지 여부를 나타냅니다.

의 경우 most분 most most most를 사용합니다.nonnull ★★★★★★★★★★★★★★★★★」nullable.

사용 가능한 모든 지정자를 다음에 나타냅니다. 기사부터:

  • null_unspecified: 이것이 기본값입니다.암묵적으로 언랩된 옵션인 Swift에 브리지 됩니다.
  • nonnull은 0이 0으로 하다재빠르다
  • nullable으로 할 수 0으로 하다재빠르다
  • null_resettable때될 수 수 읽을 때 값은 영(0)이 될 수 없지만 리셋하려면 영(0)으로 설정할 수 있습니다.속성에만 적용됩니다.

위의 표기는 속성 또는 함수/변수 컨텍스트에서 사용하는지 여부에 따라 달라집니다.

포인터와

이 기사의 저자는 또한 좋은 예를 들었다.

// property style
@property (nonatomic, strong, null_resettable) NSString *name;

// pointer style
+ (NSArray<NSView *> * _Nullable)interestingObjectsForKey:(NSString * _Nonnull)key;

// these two are equivalent!
@property (nonatomic, strong, nullable) NSString *identifier1;
@property (nonatomic, strong) NSString * _Nullable identifier2;

매우 편리한 것은

NS_ASSUME_NONNULL_BEGIN 

마지막으로

NS_ASSUME_NONNULL_END 

이렇게 하면 모든 것이 null이 아니라고 가정하는 것이 타당하기 때문에 코드레벨 'nullibis' :-'의 필요성이 무효가 됩니다.nonnull ★★★★★★★★★★★★★★★★★」_nonnull ★★★★★★★★★★★★★★★★★」__nonnull 명기되어 있지 한를 참조해 주세요.

아쉽게도 이것에도 예외가 있습니다.

  • typedef는 음음음음음음음음음음음 s s s s s s라고 하지 않습니다.__nonnullnonnull효과가 없는 것 같아서, 못생긴 이복형제를 사용해야 한다.)
  • id *sin-tax ('nullibi'는 nullibi'는 sin-tax)입니다._Nullable id * _Nonnull) <- " " " " " " " "..."
  • NSError ** 무효로 됩니다.

, 같은 수 불일치 키워드가 는, 에서는, 「 Versions」를 .__nonnull__nullable__null_unspecified컴파일러가 불만을 제기하면 교환할 수 있습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」

재미있게도, 뭔가가 내 코드에 넣었어...코드 밑줄(구식 Apple C++ 스타일남)을 싫어하기 때문에 타이핑은 하지 않았지만 몇 가지 예를 들어 다음과 같이 표시됩니다.

typedef void ( ^ DidReceiveChallengeBlock ) ( NSURLSessionAuthChallengeDisposition disposition,
                                          NSURLCredential * __nullable credential );

더 흥미로운 것은 __nullable을 삽입한 위치가 잘못되었다는 것입니다.(이크 @!

꼭 언더스코어 이외의 버전을 사용하고 싶습니다만, 에러 플래그가 붙어 있기 때문에 컴파일러에서는 사용할 수 없는 것 같습니다.

typedef void ( ^ DidReceiveChallengeBlock ) ( NSURLSessionAuthChallengeDisposition disposition,
                                          NSURLCredential * nonnull  credential );

언급URL : https://stackoverflow.com/questions/32452889/difference-between-nullable-nullable-and-nullable-in-objective-c

반응형