Forum Archive

Objcblock can get self argument

wolf71

The objc code :

            [playerNode scheduleBuffer:buffer atTime:[AVAudioTime timeWithSampleTime:sampleTime atRate:sampleRate] options:AVAudioPlayerNodeBufferInterrupts completionHandler:^{
                [playerNode stop];
                [playerNode reset];
                [self.audioEngine disconnectNodeOutput:playerNode];
            }];

pythonista code:

     def playa():

    player.stop()     #  !!!! ERROR: can't found player 
        player.reset()   #

     c_playa = ObjCBlock(playa) 

   player.scheduleBuffer_atTime_options_completionHandler_(PCMBuff,None,0,c_playa)

dgelessus

@wolf71 There is nothing special about playerNode here, it's just a normal variable. self is special in Objective-C because it's a hidden parameter of every method, but it works just like any other parameter. Blocks are a bit special in Objective-C because they can access variables in the function around them. Python functions already do this by default, so your playa function can access the playerNode variable from outside already. I don't see a self in your Python code, but if there is one, you can of course use that in the block too.

wolf71

@dgelessus sorry, the error info:

Traceback (most recent call last):
File "_ctypes/callbacks.c", line 314, in 'calling callback function'
File "/private/var/mobile/Containers/Shared/AppGroup/A2331A94-5917-4220-83BB-A1CC1ED4E5A7/Pythonista3/Documents/Research/MCSrv.py", line 71, in playa
print player.hash()
UnboundLocalError: local variable 'player' referenced before assignment

JonB

The code you copied this from was in the context of another Object, like perhaps the application's main delegate object, etc. in your case, just thing of it as a place to store your audioengine,.. global is probably fine, depending on what you are doing.

(in real objc, while blocks do have a hidden self parameter, I don't think you can normally access it without introspection... )

your problem seems to be you have not created your AVAudioEngine or AVAudioPlayerNode.
Your code is using those as globals, which is fine here, but those globals better exist!