title: premature dealloc in ARC based app
body: <p>I have a problem that seems to be a premature release of an in-use object in an ARC based app. I'm trying to create a folder on an FTP server. The relevant parts of code are below; i'll describe the problem first.</p>
  
  <p>problem with the code is, that the debug output in the </p>
  
  <pre><code>- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
  </code></pre>
  
  <p>method is never called.</p>
  
  <p>Instead, i just get an _EXC_BAD_ACCESS_ error.
  While debugging i found out two things:</p>
  
  <ol>
  <li><p>the error only appears if the following line of code (createDir method) is executed:</p>
  
  <pre><code>[ftpStream open];
  </code></pre></li>
  </ol>
  
  <p>if that message isn't sent, the rest of the code doesn't really make sense - but it doesn't crash either...</p>
  
  <ol>
  <li><p>I tracked the EXC_BAD_ACCESS down with NSZombieEnabled: With zombie objects enabled, the GDB produces the following debugger info:</p>
  
  <pre><code> *** -[FTPUploads respondsToSelector:]: message sent to deallocated instance 0x9166590
  </code></pre></li>
  </ol>
  
  <p>The referred address <strong><em>0x9166590</em></strong> is the address of my FTPUploads object.
  It looks like the streams delegate is deallocated before it can handle messages. </p>
  
  <p><strong>Why does the system deallocate an in-use object? How can i prevent it from being deallocated prematurely?</strong></p>
  
  <p>code:</p>
  
  <p>FTPUploads.h excerpt:</p>
  
  <pre><code>#import &lt;Foundation/Foundation.h&gt;
  
  enum UploadMode {
  
      UploadModeCreateDir, 
      UploadModeUploadeData
  };
  
  @class UploadDatasetVC;
  
  @interface FTPUploads : NSObject&lt;NSStreamDelegate&gt; {
  
      @private
      NSString *uploadDir;
      NSString *ftpUser;
      NSString *ftpPass;
  
      NSString *datasetDir;
      NSArray *files;
  
      /* FTP Upload fields */
      NSInputStream *fileStream;
      NSOutputStream *ftpStream;
      // some more fields...
      enum UploadMode uploadMode;
      UploadDatasetVC *callback;
  }
  
  - (id) initWithTimeseriesID: (int) aTimeseriesID 
               fromDatasetDir: (NSString *) aDir
                    withFiles: (NSArray *) filesArg 
            andCallbackObject: (UploadDatasetVC *) aCallback;
  
  - (void) createDir;
  
  @end
  </code></pre>
  
  <p>FTPUploads.m excerpt</p>
  
  <pre><code>#import "FTPUploads.h"
  #import "UploadDatasetVC"
  
  @implementation FTPUploads
  
  - (id) initWithTimeseriesID: (int) aTimeseriesID 
               fromDatasetDir: (NSString *) aDir
                    withFiles: (NSArray *) filesArg 
            andCallbackObject: (UploadDatasetVC *) aCallback {
  
      self = [super init];
  
      if (self) {
  
          uploadDir = [NSString stringWithFormat: @"ftp://aServer.org/%i/", aTimeseriesID];
          ftpUser = @"aUser";
          ftpPass = @"aPass";
  
              datasetDir = aDir;
              files = filesArg;
  
          bufferOffset = 0;
          bufferLimit = 0;
  
          index = 0;
  
          callback = aCallback;
      }
  
      return self;
  }
  
  - (void) createDir {
  
      uploadMode = UploadModeCreateDir;
      NSURL *destinationDirURL = [NSURL URLWithString: uploadDir];
  
      CFWriteStreamRef writeStreamRef = CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) destinationDirURL);
      assert(writeStreamRef != NULL);
  
      ftpStream = (__bridge_transfer NSOutputStream *) writeStreamRef;
      [ftpStream setProperty: ftpUser forKey: (id)kCFStreamPropertyFTPUserName];
      [ftpStream setProperty: ftpPass forKey: (id)kCFStreamPropertyFTPPassword];
  
      ftpStream.delegate = self;
      [ftpStream scheduleInRunLoop: [NSRunLoop currentRunLoop] forMode: NSDefaultRunLoopMode];
      // open stream
      [ftpStream open];
  
      CFRelease(writeStreamRef);
  }
  
  - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode {
  
      NSLog(@"aStream has an event: %i", eventCode);
  
      switch (eventCode) {
          // all cases handled properly
          default:
              // no event
              NSLog(@"default mode; no event");
              break;
      }
  }
  </code></pre>
  
  <p><strong>EDIT</strong>: added creation code that is used in the class UploadDatasetVC:</p>
  
  <pre><code>FTPUploads *uploads = [[FTPUploads alloc] initWithTimeseriesID: timeseries_id 
                                                  fromDatasetDir: datasetDir 
                                                       withFiles: files 
                                               andCallbackObject: self];
  [uploads createDir];
  </code></pre>