2012-05-08 6 views
0

사용자 입력에서 문자열을 가져 와서 ("exit"입력을 중단하는) 프로그램을 만들어 NSMutableArray에 저장하고 정렬합니다.문자열의 NSMutableArray 정렬 : '인식 할 수없는 selector가 인스턴스로 전송 됨'

#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; 
} 

는하지만 내가 "**"로 표시 한 선에서 예외를 얻을, 그것은 말한다 : 그것은 ID의 문자열 값을 고려하지 않습니다처럼

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

보인다. 왜? 비교기 방법을 어떻게 변경해야합니까?

답변

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

사실, 지금은 잘 작동하고 캐스트를 제거했습니다. –

관련 문제