2012-05-08 8 views
0

ユーザからの入力で文字列を取得するプログラムを作ったので、NSMutableArrayに入れて並べ替えます:文字列のNSMutableArrayをソートする: 'インスタンスに送信されたセレクタが認識されない'

#import <Foundation/Foundation.h> 
#import <Cocoa/Cocoa.h> 

NSInteger compare(id id1, id id2, void* context) 
{ 
    NSString* str1=[id1 stringValue], *str2=[id2 stringValue]; /* ****** exception here */ 
    const char* buf1, *buf2; 
    buf1=[str1 UTF8String]; 
    buf2=[str2 UTF8String]; 
    if(strcmp(buf1,buf2)<0) 
     return NSOrderedAscending; 
    else 
     return NSOrderedDescending; 
} 


int main (int argc, const char * argv[]) 
{ 
    NSAutoreleasePool* pool=[[NSAutoreleasePool alloc]init]; 
    NSMutableArray* array=[[NSMutableArray alloc]init]; 
    NSString* [email protected]""; 
    char buffer[100]; 
    NSLog(@"Type a sequence of strings, ending with 'exit', the strings will be sorted in alphabethical order"); 
    while(! [str isEqualToString:@"exit\n"]) 
    { 
     fgets(buffer,100,stdin); 
     str=[NSString stringWithUTF8String: buffer]; 
     [array addObject: str]; 

    } 
    [array sortUsingFunction: compare context: NULL]; 
    [array release]; 
    [pool drain]; 
    return 0; 
} 

しかし、私は、「**」が付いている行で例外を取得し、それは言う:

2012-05-09 00:10:14.502 CLITest[1029:903] -[NSCFString stringValue]: unrecognized selector sent to instance 0x10010cbf0 

それは、IDから文字列値を取らないように思え。どうして?コンパレータ方式をどのように変更すればよいですか?

答えて

4

id1id2(カスタムオブジェクトをソートするために、あなたのcompare関数を定義することができますので、このアプローチは便利です)、彼らはidにキャストして、関数に渡された場合でも、実際にNSString秒です。

stringValueを文字列に呼び出すことは意味がありません(実際にはNSStringにはstringValueという名前のメンバ関数がありません)。

文字列を操作するには、NSStringにキャストするだけです。

NSString *s1 = (NSString*) id1; 
NSString *s2 = (NSString*) id2; 

これは(も、それは明確コードです)(あなたもid1id2を直接操作することができます)が、キャストを使用すると、コンパイラの警告を取得するために避けることができます厳密には必要ではありません。

+0

_and_ assignをキャストする必要はありません。コンパイラはうれしく 'id'を' NSString * 'に入れます。コンパイラが目を打つことなく 'id'に' UTF8String'を送ることもできますが、読みやすくするために型を明示的にすることに同意します。 –

+0

はい、多分私はあまり明確ではありませんでした。私は答えを編集しました – Saphrosit

+0

真実、それは今うまく動作し、私はキャストを削除しました。 –

関連する問題