Search code examples
iphoneobjective-cxcode4ios5

Accessing Structure in objective C class makes error on XCode 4.2


In my iPhone app, I am using structure and access it from Objective C UIViewController class, In one of my AudioInput.h file, I have the below:

   typedef struct
    {
        AudioStreamBasicDescription format;
        AudioQueueRef queue;
        AudioQueueBufferRef buffers[ NUM_AUDIO_BUFFERS ];
        SampleBuffer samples;
        bool running;
        bool done;

        UInt32 playPos;

    }   AudioRecording;

In My ViewController MainViewController.m I implemented the AudioInputCallback() as below:

static void AudioInputCallback(
    void *userData,
    AudioQueueRef queue,
    AudioQueueBufferRef buffer,
    const AudioTimeStamp *startTime,
    UInt32 numPackets,
    const AudioStreamPacketDescription *packetDescriptions
)
{
    // TRACE( "AudioInputCallback\n" );

    MainViewController *controller = (MainViewController *) userData;
    AudioRecording *audioRecording = & controller->audioRecording;

    if( audioRecording->done )
    {
        TRACE( "AudioInputCallback: done\n" );
        return;
    }
    if( numPackets == 0 && audioRecording->format.mBytesPerPacket > 0 )
    {
        numPackets = buffer->mAudioDataByteSize / audioRecording->format.mBytesPerPacket;
    }
    if( numPackets == 0 )
    {
        TRACE( "not packets received\n" );
        return;
    }

    const SInt16 *inSamples = (const SInt16 *) buffer->mAudioData;
    const UInt32 remain = audioRecording->samples.size - audioRecording->samples.count;
    if( numPackets > remain )
    {
        numPackets = remain;
    }
    if( numPackets == 0 )
    {
        TRACE( "AudioInputCallback: no packets received\n" );
    }
    if( numPackets > 0 )
    {
        /*  Save samples.  */
        if( audioRecording->samples.data )
        {
            UInt16 *in = (UInt16 *) inSamples;
            UInt16 *out = (UInt16 *)( audioRecording->samples.data + audioRecording->samples.count );
            for( UInt32 i = 0; i < numPackets; ++i )
            {
                *out ++ = ntohs( *in++ );
            }
        }
        audioRecording->samples.count += numPackets;
    }

    if( audioRecording->samples.count < audioRecording->samples.size )
    {
        OSStatus result = AudioQueueEnqueueBuffer( queue, buffer, 0, NULL );
        if( result )
        {
            TRACE( "AudioQueueEnqueueBuffer(..) failed with status %d\n", result );
        }
    }
    else
    {
        TRACE( "AudioInputCallback: enough material, stop recording\n" );
        audioRecording->done = true;
        AudioQueueStop( audioRecording->queue, true );
    }

    [controller performSelectorOnMainThread:@selector(bufferFilled) withObject:nil waitUntilDone:NO];
}

In this method on the below line It gives error as "instance variable is protected"

MainViewController *controller = (MainViewController *) userData;
AudioRecording *audioRecording = & controller->audioRecording;

This error is occurs while running for iOS 5 with XCode 4.2 but the same code is running without any error building for below iOS 5 in XCode 4.0.2.

Can anyone help me why this error occurs? and your ideas to solve this is welcome!


Solution

  • It's nothing to do with your structure, it's to do with how you've defined the members of your UIViewController subclass. Take a look at this :

    @interface MainViewController : UIViewController
    {
    @public
        AudioRecording audioRecording1;
    
    @protected // This is the default
        AudioRecording audioRecording2;
    
    @private
        AudioRecording audioRecording3;
    }
    @end
    

    Here, this controller has three AudioRecording members. However, only audiorecording1 can be access directly from outside the class. audiorecording3 cannot be accessed by anything other than the MainViewController and audiorecording2 can be accessed by MainViewController and any subclasses of it.

    You need to make your audiorecording public if you want to access it directly without going though an accessor method (or a property).