0

正如许多人现在应该知道的那样,我是 Objective-C 的新手,我需要一些帮助来完成这个项目。我收到错误消息NSInternalInconsistencyException - nul class for object in autorelease pool

这是我的一些可能导致问题的源代码:

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 (smoothpinkjazz@gmail.com), 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", songSockPortInt];
    char *buf = malloc(MAXDATASIZE);
    NSString *identStr;
    if (buf) {
      mainSock = [[ClientSocket alloc] initWithHost:hostName portNumber:portNum];
      [mainSock connect];
      identStr = [mainSock receiveBytes: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 * authorStr = [authTB stringValue];
    NSString * titleStr = [titCB objectValueOfSelectedItem];
    NSString * albumStr = [albTB stringValue];
    NSString * song = [NSString stringWithFormat:@"%@@%@@%@ ", authorStr, titleStr, albumStr];

    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";
  NSString * titleString = [titCB objectValueOfSelectedItem];
  [self debug:[NSString stringWithFormat:@"asked to remove:\n"]];
  @try {
    int sent = [mainSock sendBytes:[removeMusicStr UTF8String]
                          OfLength:[removeMusicStr length]
                             Index:0];

    int sent2 = [mainSock sendBytes:[titleString UTF8String]
                           ofLength:[titleString 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

客户端套接字.m

#import "ClientSocket.h"

/**7
 * 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 (smoothpinkjazz@gmail.com), 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

有谁知道这里似乎发生了什么?

4

1 回答 1

0

我会打开僵尸,因为它可能试图释放已经释放的东西。

我在这里看到一个明显的问题:

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

顺便说一句,Analyzer 会发现这一点

于 2012-12-13T03:38:09.720 回答