I have a memory leak (an object is never getting dealloc'd) that I have been
debugging / troubleshooting for many, many hours.  I have narrowed it down to a
weak referenced delegate object that is being indirectly accessed through an
audio render callback. The code is doing something like this:

  static OSStatus renderCallback(__unsafe_unretained id channel,
                                 __unsafe_unretained AEAudioController 
*audioController,
                                 const AudioTimeStamp *timeStamp,
                                 UInt32 frames,
                                 AudioBufferList *audio) {
      MyClass *myClass = (MyClass *)channel;

      for (int i = 0; i < frames; i++) {
          [myClass prepareAudio]; // somehow this call causes a strong 
reference on the delegate object?
          ((int16_t *)audio->mBuffers[0].mData)[i] = 
myClass->_buffer[myClass->_index];
      }
      return noErr;
  }

  @interface MyClass ()
  @property (nonatomic, weak) id<MyClassDelegate> delegate;
  @end

  @implementation MyClass

  -(void)prepareAudio {
      // stuff
      if ([self isDone]) {
          [self.delegate didFinish];
      }
      // more stuff
  }

  @end

If I pass nil in for the delegate, then the object using this class properly
deallocates...  And if I remove the render callback and call prepareAudio in
the main thread, the object using this class properly deallocates.  So from
what I can tell it's definitely coming from the audio thread accessing the weak
delegate, and this is somehow turning into a strong reference-- I just don't
understand why that is happening.

I tried doing:

      for (int i = 0; i < frames; i++) {
          __weak MyClass *weakMyClass = myClass;
          [weakMyClass prepareAudio];
          ((int16_t *)audio->mBuffers[0].mData)[i] = 
myClass->_buffer[myClass->_index];
      }

But that made no difference...

The other thing that's really weird is, since passing in nil as a delegate 
makes the memory leak go away, I thought I could just do:

  -(void)prepareAudio {
      // stuff
      if ([self isDone]) {
          [self.delegate didFinish];
          self.delegate = nil;
      }
      // more stuff
  }

But that doesn't work either!  The main object still never deallocates..

Can anyone tell me how in the world this weak reference is becoming strong?


Patrick J. Collins
http://collinatorstudios.com

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Objc-language mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/objc-language/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to