Исключение времени выполнения 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.

Может ли кто-нибудь помочь здесь?


person Pink Jazz    schedule 12.12.2012    source источник
comment
показать, какой селектор был отправлен   -  person Max    schedule 12.12.2012
comment
Было бы полезнее включить ошибку, которую вы получаете, а не весь этот исходный код.   -  person Perception    schedule 12.12.2012
comment
Вот ошибка: 2012-12-11 21:26:44.397 MusicAppGNUstep[3500] Problem posting notification: <NSException: 0x27657a8> NAME:NSInvalidArgumentException REASON:-[ClientSocket recieveBytes:maxBytes:beginAt:]: unrecognized selector sent to instance 0x27dc108 INFO:(null) Эта ошибка возникает при запуске клиента Obj-C.   -  person Pink Jazz    schedule 12.12.2012
comment
Вообще говоря, ошибка [ClassName methodName]: unrecognized selector sent... означает, что объект ClassName использовался при попытке вызвать methodName, но methodName нигде не был найден в ClassName. В данном случае это простая орфографическая ошибка, но чаще всего это связано с тем, что в вызове использовался неправильный тип объекта.   -  person Hot Licks    schedule 12.12.2012


Ответы (1)


Это кажется мне простой опечаткой! Вы неправильно написали слово «получить» в вызываемой функции. iOS не может найти этот метод во время выполнения, поэтому выдает нераспознанное исключение селектора.

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

должно быть

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

Удачного кодирования!

person Asif Mujteba    schedule 12.12.2012
comment
Следует отметить, что в этой строке, вероятно, было предупреждение компилятора. - person Hot Licks; 12.12.2012