블록 기반 API 메서드에서 null이 아닌 nullable Objective-C 키워드를 사용하는 방법


105

다음 방법을 고려하십시오.

- (void)methodWithArg:(NSString *)arg1 andArg:(NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

new nonnullnullable 주석 키워드를 사용하여 다음과 같이 보강 할 수 있습니다.

- (void)methodWithArg:(nonnull NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

그러나 우리는 또한이 경고를받습니다 :

포인터에 null 허용 여부 유형 지정자 (__nonnull 또는 __nullable)가 없습니다.

세 번째 매개 변수 (블록 1)를 참조합니다.

문서 블록 매개 변수의 Null 허용 여부를 지정하는 방법을 예제와 함께 적용되지 않습니다. 축 어적으로 진술합니다.

형식이 단순 개체 또는 블록 포인터 인 한, 여는 괄호 바로 뒤에 밑줄이없는 형식의 nullable 및 nonnull을 사용할 수 있습니다.

나는 운없이 블록에 대한 두 키워드 중 하나를 (어느 위치 에나) 넣어 보았습니다. 또한 밑줄 접두사 변형 ( __nonnull__nullable)을 시도했습니다 .

따라서 내 질문은 : 블록 매개 변수에 대한 null 허용 의미를 어떻게 지정할 수 있습니까?

답변:


128

이것은 작동하는 것 같습니다

- (void)methodWithArg:(nonnull NSString *)arg1 
  andArg:(nullable NSString *)arg2 completionHandler:(nullable void (^)
  (NSArray * _Nullable results, NSError * _Nonnull error))completionHandler

블록과 해당 매개 변수 모두에 대해 null 허용 여부를 지정해야합니다.

편집 : 자세한 내용은 Swift 블로그를 참조하십시오.


NSError **유형 과 어떻게 작동 합니까? 컴파일러를 행복하게 만들 수없는 것 같습니다.
duhanebel

3
신속한 블로그에 따르면 : The particular type NSError ** is so often used to return errors via method parameters that it is always assumed to be a nullable pointer to a nullable NSError reference. developer.apple.com/swift/blog/?id=25
user1687195

@duhanebel 대답은 stackoverflow.com/questions/33198597/…에 있습니다 . : (NSError * _Nullable * _Nullable) error
Elise van Looij

33

에 따르면 애플 블로그 ( "Null 허용 여부 및 목표 - C") , 당신은 사용할 수 있습니다

NS_ASSUME_NONNULL_BEGINNS_ASSUME_NONNULL_END.

이러한 영역 내에서 모든 단순 포인터 유형은 nonnull. 그런 다음 nullablenullable 개체를 추가 할 수 있습니다.

NS_ASSUME_NONNULL_BEGIN

@interface MyClass: NSObject

- (void)methodWithArg:(NSString *)arg1 andArg:(nullable NSString *)arg2 completionHandler:(void (^)(NSArray *results, NSError *error))completionHandler;

@end

NS_ASSUME_NONNULL_END
  • 경우 오류가 있다 NSError **유형이어야NSError * _Nullable * _Nullable
  • object가 id *type이면 더 나은 사용 id _Nullable * _Nonnull, 그것은 당신이 원하는 _Nullable id * _Nullable유형일 수 있습니다 .
  • 객체가 NSObject *유형이면 다음과 같이 포인터 뒤에 주석을 넣어야합니다.NSObject * _Nullable * _Nonnull

노트

_Nonnull_Nullable포인터 후에 사용한다 또는 id(애플이 예제 코드에서와 AAPLListItem * _Nullable)하지만, 비 밑줄 형태 nonnull와는 nullable여는 괄호 후 사용할 수 있습니다.

당신이 아닌 밑줄 형식을 사용할 수있는 방법을 선언 내에서 그러나, 일반적인 경우에 이러한 주석 작성하는 훨씬 좋네요의 방법이 nullablenonnull한 유형이 단순 객체 또는 블록 포인터로 바로 여는 괄호 후를.

"Nullability and Objective-C" 에서 자세한 내용을 확인하십시오.

안전을 위해이 규칙에는 몇 가지 예외가 있습니다.

  • typedef형식에는 일반적으로 고유 한 null 허용 여부가 없습니다. 컨텍스트에 따라 쉽게 nullable 또는 non-nullable이 될 수 있습니다. 따라서 감사 된 지역 내에서도 typedef유형이로 간주되지 않습니다 nonnull.
  • 보다 복잡한 포인터 유형은 id *명시 적으로 주석을 달아야합니다. 예를 들어, nullable 개체 참조에 대한 nullable이 아닌 포인터를 지정하려면 다음을 사용하십시오._Nullable id * _Nonnull .
  • 특정 형식 NSError **은 메서드 매개 변수를 통해 오류를 반환하는 데 자주 사용되므로 항상 nullable NSError참조에 대한 nullable 포인터로 간주됩니다 .

_Nullable id * _Nonnull혼동 될 수는 id _Nullable * _Nonnull더 나은 이해이다.

_Nonnull_Nullable포인터 후에 사용 또는한다 id(애플이 예제 코드에서와AAPLListItem * _Nullable )


약한 속성의 경우 _Nullable이 적용됩니다.
동진 동서

3

다음과 같이 할 수도 있습니다.

- (id __nullable)methodWithArg:(NSString * __nullable)arg1
                        andArg:(NSString * __nonnull)arg2
             completionHandler:(void (^ __nonnull)(NSArray * __nonnull results, NSError * __nullable error))completionHandler;

그것은 당신이 더 좋아하는 구문에 달려 있습니다.


2

헤더 파일에서 완성을 정의하기 위해 이렇게했습니다.

typedef void (^PublicEventsHandler) (BOOL success, NSArray * _Nullable publicEvents);

물론 받아 들여진 답변에 동의합니다.


0

Apple 개발자 블로그 : The Core : _Nullable 및 _Nonnull

형식이 단순 개체 또는 블록 포인터 인 한, 여는 괄호 바로 뒤에 밑줄이없는 형식의 nullable 및 nonnull을 사용할 수 있습니다 .

밑줄이없는 형식은 밑줄이있는 형식보다 더 좋지만 헤더의 모든 유형에 적용해야합니다 .


네,하지만 비 밑줄 (더 좋은) 사람하지 블록 선언에서 작업
폴 Bruneau

-2

다음은 NSError ** 케이스에 사용한 것입니다.

-(BOOL) something:(int)number withError:(NSError *__autoreleasing  __nullable * __nullable)error;

1
애플 에 대해 말했다 NSError **, 당신은 Null 허용 여부를 지정할 필요가 없습니다.
DawnSong
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.