2012-12-12 33 views
0

我工作的客戶機/服務器軟件包在Objective-C,和我得到一個在運行時「無法識別的選擇發送到實例」的錯誤。我是Objective-C的新手,所以我想在這裏尋求幫助。Objective-C的運行時異常 - 無法識別的選擇發送到實例

這裏有兩個代碼文件,可能是有用的:

GuiController.m

#import "GuiController.h" 
    #import "AppDelegate.h" 
    #import "ClientSocket.h" 
    #import "UploaderThread.h" 
    #import "DownloaderThread.h" 


    // to see debug messages, change NO below to YES 
    #define DEBUGON YES 
    // buffer size for reading byte arrays to/from server 
    #define MAXDATASIZE 1024 
    /** 
    * Foundations of Distributed Applications 
    * see http://pooh.poly.asu.edu/Cst420 
    * @author Christopher Sosa ([email protected]), ASU Polytechnic, Software Engineering 
    * @version December 2012 
    */ 

    @implementation GuiController 

    - (id) initWithDelegate: (AppDelegate*) theDelegate 
        host: (NSString*) hostName 
        port: (NSString*) portNum { 
    // set self to result of initializing parent. If initialization succeeds 
     if ((self = [super init])) { 
    // set properties and increment the reference count for its object. 
    appDelegate = [theDelegate retain]; 
    albTB = [appDelegate albumTB]; 
    [albTB setStringValue:[NSString stringWithFormat:@"Probably should look for server %s:%s",[hostName UTF8String],[portNum UTF8String]]]; 
    titCB = [appDelegate titleCB]; 
    [titCB setDelegate:self]; 
    authTB = [appDelegate authorTB]; 
    [authTB setDelegate:self]; 
    host = hostName; 
    port = portNum; 
    int songSockPortInt = [port intValue] + 100; 
    NSString *songSockPort = [NSString stringWithFormat:@"%d", songSockPort]; 
    char *buf = malloc(MAXDATASIZE); 
    NSString *identStr; 
    if (buf) { 
     mainSock = [[ClientSocket alloc] initWithHost:hostName portNumber:portNum]; 
     [mainSock connect]; 
     identStr = [mainSock recieveBytes:buf maxBytes:MAXDATASIZE beginAt:0]; 
     ident = [identStr intValue]; 
     songSock = [[ClientSocket alloc] initWithHost:host portNumber:songSockPort]; 
     [songSock connect]; 
    } 
    [identStr release]; 
    free(buf); 
     } 
     return self; 
    } 

    - (void) dealloc { 
     [appDelegate release]; 
     [albTB release]; 
     [titCB release]; 
     [authTB release]; 
     [mainSock release]; 
     [songSock release]; 
     [super dealloc]; 
    } 

    - (void) saveLib { 
     [self debug:[NSString stringWithFormat:@"asked to save.\n"]]; 
     NSString * saveStr = @"save"; 
     char * buf = malloc(MAXDATASIZE); 
     if (buf) { 
      int sent = [mainSock sendBytes:[saveStr UTF8String] OfLength:[saveStr length] 
      Index:0]; 
      NSString* retStr = [mainSock receiveBytes: buf maxBytes:MAXDATASIZE beginAt:0]; 
      [[appDelegate albumTB] setStringValue: 
      [NSString stringWithFormat:@"Save result: %s",[retStr UTF8String]]]; 
      free(buf); 
      [self debug:[NSString stringWithFormat:@"save return: %s\n", 
      [retStr UTF8String]]]; 
     } 
     [[appDelegate albumTB] setStringValue: [NSString stringWithFormat:@"Saved"]]; 
    } 

    - (void) restoreLib { 
     NSString * restoreStr = @"restore"; 
     [self debug:[NSString stringWithFormat:@"asked to restore.\n"]]; 
     char * buf = malloc(MAXDATASIZE); 
     if (buf) { 
      int sent = [mainSock sendBytes:[restoreStr UTF8String] OfLength:[restoreStr length] Index:0]; 
      NSString* retStr = [mainSock receiveBytes: buf maxBytes:MAXDATASIZE beginAt:0]; 
      [[appDelegate albumTB] setStringValue: 
      [NSString stringWithFormat:@"Restore result: %s",[retStr UTF8String]]]; 
      free(buf); 
      [self debug:[NSString stringWithFormat:@"restore return: %s\n", 
      [retStr UTF8String]]]; 
     } 
     [[appDelegate albumTB] setStringValue:[NSString stringWithFormat:@"Restored"]]; 
    } 

    - (void) addMD { 
     NSString * addMusicStr = @"add"; 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     ClientSocket *addSock; 
     UploaderThread * uploader; 
     @try { 
      [self debug:[NSString stringWithFormat:@"openWav called:\n"]]; 
      NSOpenPanel *panel; 
      NSString *path; 

      panel = [NSOpenPanel openPanel]; 
      [panel setAllowsMultipleSelection: NO]; 
      [panel runModalForTypes: [NSSound soundUnfilteredFileTypes]]; 

      path = [[panel filenames] objectAtIndex: 0]; 

      if (sound != nil) { 
       [sound stop]; 
       [sound release]; 
      } 
      sound = [[NSSound alloc] initWithContentsOfFile: path byReference: NO]; 
      if (!sound) { 
       NSRunAlertPanel (@"Error", @"Could not open selected file", @"OK", nil, nil); 
       return; 
      } 
      NSString * song = [NSString stringWithFormat:@"%@@%@@%@ ", [authTB stringValue], [titCB stringValue], [albTB stringValue]]; 

      addSock = [[ClientSocket alloc] initWithHost:host portNumber:@"9001"]; 
      [addSock connect]; 
      int sent = [mainSock sendBytes:[addMusicStr UTF8String] OfLength:[addMusicStr length] Index:0]; 
      int sentSong = [mainSock sendBytes:[song UTF8String] OfLength:[song length] Index:0]; 
      uploader = [[UploaderThread alloc] initWithName:path client:self socket:addSock]; 
      [(NSThread*)uploader start]; 
     } @catch (NSException *e) { 
      [self debug:[NSString stringWithFormat:@"%@ Exception (%@)", [e name], [e reason]]]; 
     } 
     [uploader release]; 
     [addSock release]; 
     [sound setDelegate: self]; 
     [pool release]; 
     [self refreshMD]; 
    } 

    - (void) removeMD { 
     NSString * removeMusicStr = @"remove"; 
     [self debug:[NSString stringWithFormat:@"asked to remove:\n"]]; 
     @try { 
      int sent = [mainSock sendBytes:[removeMusicStr UTF8String] OfLength:[removeMusicStr length] Index:0]; 
      int sent2 = [mainSock sendBytes:[[titCB stringValue] UTF8String] ofLength:[[titCB stringValue] length] Index:0]; 
     } @catch (NSException *e) { 
      [self debug:[NSString stringWithFormat:@"%@ Exception (%@)", [e name], [e reason]]]; 
     } 
     [[appDelegate albumTB] 
     setStringValue:[NSString stringWithFormat:@"Music Description Removed"]]; 
    } 

    - (void) refreshMD { 
     NSString * refreshMusicStr = @"refresh"; 
     [self debug:[NSString stringWithFormat:@"asked to refresh\n"]]; 
     [[appDelegate albumTB] 
     setStringValue:[NSString stringWithFormat:@"Music Descriptions Refreshed"]]; 
    } 

    - (void) playMD { 
     NSString * playMusicStr = @"play"; 
     ClientSocket *playSock; 
     DownloaderThread *downloader; 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     @try { 
      playSock = [[ClientSocket alloc] initWithHost:host portNumber:@"9002"]; 
      [playSock connect]; 
      int sent = [mainSock sendBytes:[playMusicStr UTF8String] OfLength:[playMusicStr length] Index:0]; 

      [self debug:[NSString stringWithFormat:@"asked to play:\n"]];; 
      downloader = [[DownloaderThread alloc] initWithClient:self socket:playSock]; 
     } @catch (NSException *e) { 
      [self debug:[NSString stringWithFormat:@"%@ Exception (%@)", [e name], [e reason]]]; 
     } 
     [playSock release]; 
     [downloader release]; 
     [pool release]; 
    } 

    - (void) comboBoxSelectionDidChange: (NSNotification*)notification { 
     NSComboBox*titCB = [appDelegate titleCB]; 
     NSString* selected = [titCB objectValueOfSelectedItem]; 
     [self debug:[NSString stringWithFormat:@"selected title: %s\n", [selected UTF8String]]]; 

    } 

    - (void) debug: (NSString*) aMessage{ 
     if(DEBUGON){ 
     NSString * fileName = @"/Users/lindquis/Courses/Cst420/Assigns/" "AssignsF12/Assign3/SampleAssign3/GUIMessages.txt"; 
     NSFileHandle* fh = [NSFileHandle fileHandleForWritingAtPath: fileName]; 
     [fh seekToEndOfFile]; 
     [fh writeData: [aMessage dataUsingEncoding:NSUTF8StringEncoding]]; 
     [fh closeFile]; 
     //printf("debug: %s\n", [aMessage UTF8String]); 
     } 
    } 

    @end 

ClientSocket.m

#import "ClientSocket.h" 

/** 
* SER 321 Foundations of Distributed Applications, 
* based on the simple server and client sockets in C by Jeez. 
* See http://pooh.poly.asu.edu/Cst420 
* @author Christopher Sosa ([email protected]), ASU Polytechnic, Engineering 
* @version December 2012 
*/ 

// get sockaddr, IPv4 or IPv6: 
void *get_in_addr(struct sockaddr *sa){ 
    if (sa->sa_family == AF_INET) { 
     return &(((struct sockaddr_in*)sa)->sin_addr); 
    } 
    return &(((struct sockaddr_in6*)sa)->sin6_addr); 
} 

@implementation ClientSocket 
- (id) initWithHost: (NSString*) host portNumber: (NSString*) port { 
    self = [super init]; 
    hostName = host; 
    [hostName retain]; 
    portNum = port; 
    [portNum retain]; 
    return self; 
} 

- (BOOL) connect { 
    connected = YES; 
    memset(&hints, 0, sizeof hints); 
    hints.ai_family = AF_UNSPEC; 
    hints.ai_socktype = SOCK_STREAM; 
    if ((rv = getaddrinfo([hostName UTF8String], [portNum UTF8String], &hints, &servinfo)) != 0) { 
     fprintf(stderr, "client error getting host address: %s\n", gai_strerror(rv)); 
     connected = NO; 
    } 
    // loop through all the results and connect to the first we can 
    for(p = servinfo; p != NULL; p = p->ai_next) { 
     if ((sockfd = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1){ 
      perror("client error creating socket"); 
      connected = NO; 
      continue; 
     } 
     int callret = connect(sockfd, p->ai_addr, p->ai_addrlen); 
     if (callret == -1) { 
      #if defined(WINGS) 
      closesocket(sockfd); 
      #else 
      close(sockfd); 
      #endif 
      #if defined(WINGS) 
      //printf("client failed to connect.\n"); 
      #else 
      inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); 
      printf("client failed to connect to %s\n", s); 
      #endif 
      //perror("client error connecting"); 
      connected = NO; 
      continue; 
     } 
     break; 
    } 
    if (p == NULL) { 
     printf("client failed to connect\n"); 
     connected = NO; 
    } else{ 
     #if defined(WINGS) 
     //printf("client connected\n"); 
     #else 
     inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s); 
     printf("client connected to %s\n", s); 
     #endif 
     connected = YES; 
    } 
    return connected; 
} 

- (int) sendBytes: (char*) byteMsg OfLength: (int) msgLength Index: (int) at{ 
    int ret = send(sockfd, byteMsg, msgLength, 0); 
    if(ret == -1){ 
     NSLog(@"client error sending bytes"); 
    } 
    return ret; 
} 

- (NSString*) receiveBytes: (char*) byteMsg 
       maxBytes: (int) max 
       beginAt: (int) at { 
    int ret = recv(sockfd, byteMsg, max-1, at); 
    if(ret == -1){ 
     NSLog(@"client error receiving bytes"); 
    } 
    byteMsg[ret+at] = '\0'; 
    NSString * retStr = [NSString stringWithUTF8String: byteMsg]; 
    return retStr; 
} 

- (BOOL) close{ 
    connected = NO; 
    return YES; 
} 

- (void) dealloc { 
    [hostName release]; 
    [portNum release]; 
    [super dealloc]; 
} 

@end 

基本上,我是想我的翻譯Java客戶端到Objective-C。 ClientSocket.m文件主要由教師提供,只做了一些修改。服務器仍然使用Java編寫。

任何人都可以請幫助嗎?

+0

顯示選擇器發送的內容 – Max

+0

包含錯誤信息會更有幫助,而不是所有源代碼。 – Perception

+0

以下是錯誤: '二〇一二年十二月一十一日21:26:44.397 MusicAppGNUstep [3500]問題發佈通知: NAME:NSInvalidArgumentException原因: - [ClientSocket的recieveBytes:maxBytes:beginAt:]:無法識別選擇發送到實例0x27dc108 INFO:(null)' 當我啓動Obj-C客戶端時發生此錯誤。 –

回答

2

這在我看來是一個簡單的打字錯誤!您在被調用的函數中拼寫了「接收」字。 iOS在運行時無法找到該方法,從而引發無法識別的選擇器異常。

identStr = [mainSock recieveBytes:buf maxBytes:MAXDATASIZE beginAt:0]; 

應該

identStr = [mainSock receiveBytes:buf maxBytes:MAXDATASIZE beginAt:0]; 

編碼快樂!

+1

應該指出的是,這條線上可能存在編譯器警告。 –

相關問題