2012-02-18 18 views

答えて

2

私は、クラスのいくつかの既存の関数を上書きするためにサブクラス化する必要なく、既存のクラスに繰り返し使用するいくつかの便利な関数を追加する必要があるときにカテゴリを使用しました。例えば

、私は空の文字列をチェックし、または文字列の先頭と末尾の空白をすべて削除したい:

.hファイル:

@interface NSString (Extension) 

-(BOOL)isEmptyString; 
-(NSString *)trimLeadingAndTrailingWhiteSpaces; 

@end 

.mファイル:

@implementation NSString (Extension) 

-(BOOL)isEmptyString 
{ 
    NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; 
    if (myString.length == 0) 
     return TRUE; 
    else 
     return FALSE; 
} 

-(NSString *)trimLeadingAndTrailingWhiteSpaces 
{ 
    NSString *myString = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
    return myString; 
} 
@end 

それを使用するには、次の

someString = [someString trimLeadingAndTrailingWhiteSpaces]; 

if ([someString isEmptyString]) 
     { 
     //someString is empty, do whatever! 
     } 
+1

obj-cでは、YES/NOを使用し、TRUE/FALSEを使用しないでください。 – Sulthan

+0

良い点。私はTRUE/FALSEで使用されています。 – user523234

+1

この場合は、とにかく 'return(myString.length == 0)'にする必要があります:) – Sulthan

3

既存のクラスに機能を追加する必要がある場合。

たとえば、お使いのアプリがNSDateまたはNSStringのインスタンスで動作していて、いくつかの機能を追加したいとします。サブクラスにシステムメソッドを強制的に戻すことはできないので、そのサブクラスに機能を追加することはできません。

ちょうどAPIの例に見て:

1/NSDictionaryのは、ファイルの属性を保持するために使用し、ファイルサイズを返すメソッドを持っています。
2/NSStringには、図面を拡張するUIカテゴリがあります。描画可能な文字列の別のサブクラスを必要としないことに注意してください。すべての文字列に描画する機能が必要です。

0

スルタンはそれをうまく説明します。ここには、カテゴリーを追加することによってNSStringの機能を拡張するコードexampleがあります。このようにカテゴリを使用すると、実装を持たないクラスをサブクラス化せずに継承することができます。

0

にメソッドを追加する場合は、カテゴリを使用します。 クラスの既存のメソッドの機能を変更する場合は、サブクラスを作成します。

既存のメソッドを置き換えるためにカテゴリを使用することは可能ですが、サブクラスでオーバーライドするようなものですが、カテゴリを使用しないでください。 3つの理由があります:1)元の方法へのアクセスを失う。 2)既存のコードを破ることはありません。 3)複数のカテゴリが同じメソッドを「オーバーライド」しようとすると、そのクラスが終了するメソッドは未定義です。基本的に、クラスは最後のカテゴリのメソッドをクラスに適用しますが、適用されるカテゴリの順序は信頼できません。それは混乱のためのレシピなので、やってはいけません。

したがって、カテゴリーを使用して、+(NSData*)dataWithCryptographicallyRandomBytes:(NSUInteger)lengthまたは-(void)base64DecodeなどのメソッドをNSDataに追加できます。しかし、-writeToFile:atomically:のような既存のメソッドの動作を変更したい場合は、NSDataのサブクラスを作成し、そこに新しい機能を実装する必要があります。 1つは、オーバーライドで既存の動作を使用したい場合があり、サブクラス化では[super writeToFile:file atmoically:YES]を呼び出すことで可能になります。また、ここでサブクラスを使用すると、新しい動作が自分のコードにのみ影響することになります。新しい機能が期待できないフレームワーク内のNSDataの使用には影響しません。

0

カテゴリはJavaインターフェイスに似ています(Javaでは実装はオプションではありません) - メソッドをグループ化してオブジェクトを特定のAPIに応答させる方法で、クラスの種類に依存しません。継承は、追加のivarsを追加する必要があり、新しいクラスがisa関係(student isa person)に一致する必要がある場合には意味があります。いくつかのユーティリティメソッドを追加してもisaの問題は発生しません。これは通常、プロトコルで行われます。カテゴリは、問題のメソッドがオプションである代理人でよく使用されます。

1

継承によって提供される機能の一部を実現する簡単な方法として、カテゴリを参照しています。継承によって提供されないカテゴリが他にもあります。カテゴリを使用すると、サブクラス化せずに既存のクラスの機能を拡張できます。それらを使用して、クラス内の既存のメソッドを置き換えることもできます。カテゴリメソッドは、元のクラスの子孫を指示するサブクラスとは異なり、既存のクラスに一種のものです。カテゴリメソッドが目的のクラスに追加されると、それはあなたが作成していないクラスを含むクラスのすべてのインスタンスで使用できます。

たとえば、プロジェクトのすべてのデータで使用する必要がある暗号化機能が必要な場合、ほとんどのデータでは保存と操作にNStringのみが使用されます。あなたはそれについて移動できる方法の一つは、NSStringの

NSStringの-Encryption.h

@interface NSString (Encryption) 
    -(NSString*) encrypt; 
    @end 

NSStringの-Encryption.m

#import "NSString-Encryption.h" 
@implementation NSString (Encryption) 
-(NSString*) encrypt 
{ 
// your encryption method here 
    return encryptedString; 
} 
@end 

UseNSString-encryption.mのカテゴリを作成することです

NSString *testString = @"this is test"; 
NSString *encryptedString = [testString encrypt]; 

このように、カテゴリはサブクラスよりも使いやすいことがわかります。このメソッドは、NSStringから継承するNSMutableStringからも呼び出すことができます。それは強力です。

カテゴリを使用して、クラスの既存のメソッドを置き換えることもできます。

カテゴリの別の使用法は、プライベートメソッドとして使用することができます。目的は、メソッドの正式なプライベート指定を持たないためです。これは、.hファイルの代わりに.mファイルにカテゴリを入れて行われます。

Phone.h

@interface Phone:NSObject 
-(void) call; 
@end 

Phone.m

@interface Phone(Private) 
     -(void) validatePhoneEntry:(NSString*) phoneNumber; 
    @end 

    @implementation Phone 

    -(void) validatePhoneEntry:(NSString*) phoneNumber 
    { 

    } 

    -(void) call 
    { 
    } 

    @end 

カテゴリの欠点は、あなたがクラスにメンバ変数を追加する必要がある場合は、それらを使用傾けることです。

関連する問題