18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[NSNull null]か確認するなら[obj isNull]だと思うんだ

Last updated at Posted at 2014-05-06

昔々読んだ本(リファクタリング)にNullObjectパターンなるものが紹介されていて、その中でのオブジェクトがnullオブジェクトかの確認方法はisNullだった。rubyでもnilかどうかの判定はobj.nil?、ものすごく分かりやすい。

Objective-CでのNSNullオブジェクトかの比較方法は下記の通り。ちょっとだけだけど冗長な感じがする。

-(BOOL)test:(NSNumber*)value {
  if( value == nil || [value isEqual:[NSNull null]] ) {
    return NO;
  }
  return YES;
}

nilの比較は100歩譲るとして、[value isNull]くらいできても良いと思うんだ.
という訳で実現してみた。

※ 職場では、環境の根底を勝手に変更すると混乱すること必至なので、関係者からの同意を得てからにしましょう。

NSObjectにisNullを追加する

NSObjectにカテゴリを追加してisNullメソッドを追加します。

NSObject+isNull.h

@interface NSObject (isNull)
-(BOOL)isNull;
@end

NSObject+isNull.m

#import "NSObject+isNull.h"

@implementation NSObject (isNull)
-(BOOL)isNull {
    return [[NSNull null] isEqual:self];
}
@end

プリコンパイルヘッダにNSObject+isNull.hを追加する.

デフォルトではプリコンパイルヘッダが有効になっていると思うので、pchファイルにNSObject+isNull.hを追加します。これでプロジェクト内の全てのソースファイルから、NSObject+isNull.hがインクルードされます。ソースファイル毎に#import "NSObject+isNull.h"する必要がなくなります。

プロジェクト名-Prefix.pch

#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import "NSObject+isNull.h"
#endif

動作確認

これで次のようにかけるようになりました。

-(BOOL)test:(NSNumber*)value {
  if( value == nil || [value isNull] ) {
    return NO;
  }
  return YES;
}

…value == nil、邪魔だなー。
ここまで書いてだけど、[NSNull isNull:value]の方が良い気がしてきた.
書き直します。

[NSNull isNull]

// NSNull+isNull.h
#import <Foundation/Foundation.h>

@interface NSNull (isNull)
+(BOOL)isNull:(id)obj;
@end
// NSNull+isNull.m
import "NSNull+isNull.h"

@implementation NSNull (isNull)
+(BOOL)isNull:(id)obj {
    return obj == nil || [[NSNull null] isEqual:obj];
}
@end 
// プロジェクト名.pch
#ifdef __OBJC__
    #import <UIKit/UIKit.h>
    #import <Foundation/Foundation.h>
    #import "NSNull+isNull.h"
#endif

動作確認

-(BOOL)test:(NSNumber*)value {
  if([NSNull isNull:value]) {
    return NO;
  }
  return YES;
}

余談

あまり意味がない、言葉遊びのように感じられるかもしれませんが、
この変更により以下のようなメリットがあると思います。

  • コードの意図が明確になった
  • value = nilのようなミスをしなくてすむ
  • 「nilでない場合」が書きやすくなった(![NSNull isNull:value]ですむ。)
  • nilか[NSNull null]か気にしなくてよくなった
18
18
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?