Error after leave scene with timers

So I have a scene where I have 3 images at the top - some arrows the user can use to change between them manually and a scroll view with text below.

Below that is a button which will play audio and automatically changes the images above at specific times in the audio.

However if I play the audio then leave the scene it seems the timers are started, when I leave the scene they dont seem to stop and the function they call still happens in which case the object doesnt exist anymore giving an error.

The bold line below is the one that comes up as an error - a nil object

 function changeImage()
        myCurrentImageC2:removeSelf()
        myCurrentImageC2 = nil
        myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,181)
        myCurrentImageC2.x = display.contentCenterX
        myCurrentImageC2.y = display.contentCenterY-70
        myCurrentImageC2.currentImageIndex = 2
        sceneGroup:insert( myCurrentImageC2 )
        
    end

print("location1") local leftSide = display.screenOriginX; local rightSide = display.contentWidth-display.screenOriginX; local topSide = display.screenOriginY; local bottomSide = display.contentHeight-display.screenOriginY; --------------------------------------------------------------------------------------- local composer = require "composer" local scene = composer.newScene() local widget = require "widget" math.randomseed(os.time()) local audioSound = audio.loadSound("audio/dublin/2\_northWilliamSteet.mp3") local isChannel1Playing = audio.isChannelPlaying( 1 ) local function btnTouch( event ) if event.phase == "ended" then print ("button pressed") composer.gotoScene(event.target.btnDestination, {time=250, effect="crossFade"}) return true end end local function myAudio( event ) if event.phase == "ended" then if isChannel1Playing == false then event.target.audioChannel = audio.play(audioSound,{ channel=1}) changeTimer = timer.performWithDelay( 40000, changeImage ) changeTimer2 = timer.performWithDelay( 60000, changeImage2 ) end return true end end -- Called when the scene's view does not exist: function scene:create( event ) local sceneGroup = self.view local bg = display.newImageRect("images/bg\_legacy.jpg", 360, 568) bg.x = display.contentCenterX bg.y = display.contentCenterY sceneGroup:insert( bg ) -- code to slide through locations -- myImagesC2 = {"images/Dublin/2a.png", "images/Dublin/2b.png", "images/Dublin/2c.png"} -- name of images currentImageIndex = 1 -- this is index to track your current image -- display the first image myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,181) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) -- Function to handle back and forward buttons local function handleButtonEvent( event ) print( currentImageIndex ) if ( "ended" == event.phase ) then if event.target.id == "back" and currentImageIndex \> 1 then print( "Back" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex - 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex - 1 myCurrentImageC2.currentImageIndex = currentImageIndex elseif event.target.id == "fwd" and currentImageIndex \< 3 then print( "fwd" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex + 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex + 1 myCurrentImageC2.currentImageIndex = currentImageIndex end return true end end function changeImage() myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,181) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 2 sceneGroup:insert( myCurrentImageC2 ) end function changeImage2() myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[3],240,181) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 3 sceneGroup:insert( myCurrentImageC2 ) end -- Create a ScrollView local scrollView = widget.newScrollView { left = 0, top = display.contentCenterY+40, width = display.contentWidth, height = 150, topPadding = 10, bottomPadding = 20, id = "onBottom", horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, hideBackground = true, } --Create a large text string local myText =[[Mary Aikenhead and her first companion Alicia Walsh, having completed their novitiate, arrived in Dublin from York on 22nd August 1815. They went to live in a house in North William Street, where they were to take over the care of a number of orphans. It was here that the two sisters made their first Profession of Vows on 1st September 1815. On that day Mary Aikenhead was appointed Superior General of the new congregation and Sr. (Mary) Catherine, novice mistress. Two days later they received the first postulant – Catherine Lynch from Drogheda. Two months after their arrival the sisters opened a day school, to which the poor children of the neighbourhood flocked in great numbers. Gradually the number of sisters increased and they were able to engage in the work originally envisaged by Mary Aikenhead – visitation of the sick poor in their homes. The words of Dr. Murray to Mary Aikenhead while she was still a novice in York had now become a reality: ‘Your family in future are to be the poor of Jesus Christ.’]] --Create a text object containing the large text string and insert it into the scrollView local myText = display.newText( myText, display.contentCenterX, 0, 300, 0, "Gotham-Book", 14) myText:setFillColor( 0 ) myText:setTextColor( 0, 0, 0 ) myText.anchorY = 0.0 -- Top --------------------------------myText:setReferencePoint( display.TopCenterReferencePoint ) -- myText.y = titleText.y + titleText.contentHeight + 10 scrollView:insert( myText ) sceneGroup:insert( scrollView ) local backBtn = display.newImageRect("images/Dublin/mountjoy.jpg", 360, 40) backBtn.x = display.contentCenterX backBtn.y = display.screenOriginY+20; backBtn.btnDestination = "dublin" backBtn:addEventListener( "touch", btnTouch ) sceneGroup:insert( backBtn ) local audioBtn = display.newImageRect("images/playAudioVisual.jpg", 360, 40) audioBtn.x = display.contentCenterX audioBtn.y = bottomSide -20 audioBtn:addEventListener( "touch", myAudio ) audioBtn:toFront( ) sceneGroup:insert( audioBtn ) arrowLeft = display.newImageRect("images/arrowLeftDark.png", 12, 21) arrowLeft.x = display.screenOriginX+20 arrowLeft.y = display.contentCenterY-80 arrowLeft:toFront( ) arrowLeft.id = "back" arrowLeft:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowLeft ) arrowRight = display.newImageRect("images/arrowRightDark.png", 12, 21) arrowRight.x = display.contentWidth-display.screenOriginX -20; arrowRight.y = display.contentCenterY-80 arrowRight:toFront( ) arrowRight.id = "fwd" arrowRight:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowRight ) local function moveToFront( ) arrowRight:toFront( ) arrowLeft:toFront( ) end end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if "did" == phase then print( "1: show event, phase did" ) local sceneName = composer.getSceneName( "previous" ) if sceneName ~= nil then composer.removeScene( sceneName, true ) end end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if "will" == phase then print( "1: hide event, phase will" ) -- cancel timer if isChannel1Playing == true then timer.cancel( changeTimer ); changeTimer = nil timer.cancel( changeTimer2 ); changeTimer2 = nil; end -- remove audio audio.stop() audio.dispose( audioSound ) end end function scene:destroy( event ) print( "((destroying scene 1's view))" ) local sceneGroup = self.view end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

You never change isChannel1Playing to true once you start playing the audio.

Rob

I thought this was a read value that returns if the channel is playing? I expected it to return true automatically once the audio is playing…is this not the case?

https://docs.coronalabs.com/api/library/audio/isChannelPlaying.html

Right, you called it once at the top of the scene. It runs exactly once. Code in the main chunk of the scene only executes once until the scene is un-requried and reloaded. So if you don’t remove the scene before going back it won’t run that code again.

But in your scene, your button starts the music, it’s best to set the flag there.

Rob

Cool, gotcha.

Thanks Rob

So I changed my code a bit and added in some extra functionality so that when automatic part takes place with the audio playing i remove the arrows so the user can mess with it. Then when the audio finishes I put the arrows back in so they can manually edit it.

When I leave the scene I am getting an error though in the changeImage function about the removeSelf()

Line: 141
Attempt to call method ‘removeSelf’ (a nil value)

Any ideas what the reason is?

print("location1") local leftSide = display.screenOriginX; local rightSide = display.contentWidth-display.screenOriginX; local topSide = display.screenOriginY; local bottomSide = display.contentHeight-display.screenOriginY; --------------------------------------------------------------------------------------- local composer = require "composer" local scene = composer.newScene() local widget = require "widget" math.randomseed(os.time()) -- Called when the scene's view does not exist: function scene:create( event ) local sceneGroup = self.view local audioSound = audio.loadSound("audio/cork/2\_dauntsSquare.mp3") local isChannel1Playing = audio.isChannelPlaying( 1 ) local function btnTouch( event ) if event.phase == "ended" then print ("button pressed") composer.gotoScene(event.target.btnDestination, {time=250, effect="crossFade"}) return true end end local function myAudio( event ) if event.phase == "ended" then if isChannel1Playing == false then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) arrowLeft.isVisible = false arrowRight.isVisible = false event.target.audioChannel = audio.play(audioSound,{ channel=1,onComplete = messageMe}) isChannel1Playing = true changeTimer = timer.performWithDelay( 23000, changeImage ) end return true end end function messageMe( event ) if ( event.completed ) then arrowLeft.isVisible = true arrowRight.isVisible = true myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) print("audio finished") isChannel1Playing = false end end local bg = display.newImageRect("images/bg\_legacy.jpg", 360, 568) bg.x = display.contentCenterX bg.y = display.contentCenterY sceneGroup:insert( bg ) -- code to slide through locations -- myImagesC2 = {"images/Cork/2a.png", "images/Cork/2b.png" } -- name of images currentImageIndex = 1 -- this is index to track your current image -- display the first image myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) -- Function to handle back and forward buttons local function handleButtonEvent( event ) if ( "ended" == event.phase ) then if event.target.id == "back" and currentImageIndex \> 1 then print( "Back" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex - 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex - 1 myCurrentImageC2.currentImageIndex = currentImageIndex elseif event.target.id == "fwd" and currentImageIndex \< 2 then print( "fwd" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex + 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex + 1 myCurrentImageC2.currentImageIndex = currentImageIndex end return true end end function changeImage() if myCurrentImageC2 ~= nil and isChannel1Playing == true then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 2 sceneGroup:insert( myCurrentImageC2 ) end end -- Create a ScrollView local scrollView = widget.newScrollView { left = 0, top = display.contentCenterY+40, width = display.contentWidth, height = 150, topPadding = 10, bottomPadding = 20, id = "onBottom", horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, hideBackground = true, } --Create a large text string local myText =[[Their eldest child, Mary, was born on 19th January, 1787 in the house in Daunt's Square. Historically, Cork was built on marshland and at that time had a network of canals, bridges and narrow laneways criss-crossing the city from the North Gate Bridge to the South Gate Bridge. Mary's father was a doctor and he owned a pharmacy trading under the name of Aikenhead & Dupont. Over 80,000 people lived in the crammed laneways around Cork city where clean water was not readily available. The living conditions and health of the poor in particular were appalling.]] --Create a text object containing the large text string and insert it into the scrollView local myText = display.newText( myText, display.contentCenterX, 0, 300, 0, "Gotham-Book", 14) myText:setFillColor( 0 ) myText:setTextColor( 0, 0, 0 ) myText.anchorY = 0.0 -- Top --------------------------------myText:setReferencePoint( display.TopCenterReferencePoint ) -- myText.y = titleText.y + titleText.contentHeight + 10 scrollView:insert( myText ) sceneGroup:insert( scrollView ) local backBtn = display.newImageRect("images/Cork/daunts.jpg", 360, 40) backBtn.x = display.contentCenterX backBtn.y = display.screenOriginY+20; backBtn.btnDestination = "cork" backBtn:addEventListener( "touch", btnTouch ) sceneGroup:insert( backBtn ) local audioBtn = display.newImageRect("images/playAudioVisual.jpg", 360, 40) audioBtn.x = display.contentCenterX audioBtn.y = bottomSide -20 audioBtn:addEventListener( "touch", myAudio ) audioBtn:toFront( ) sceneGroup:insert( audioBtn ) arrowLeft = display.newImageRect("images/arrowLeftDark.png", 12, 21) arrowLeft.x = display.screenOriginX+20 arrowLeft.y = display.contentCenterY-80 arrowLeft:toFront( ) arrowLeft.id = "back" arrowLeft:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowLeft ) arrowRight = display.newImageRect("images/arrowRightDark.png", 12, 21) arrowRight.x = display.contentWidth-display.screenOriginX -20; arrowRight.y = display.contentCenterY-80 arrowRight:toFront( ) arrowRight.id = "fwd" arrowRight:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowRight ) local function moveToFront( ) arrowRight:toFront( ) arrowLeft:toFront( ) end end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if "did" == phase then print( "1: show event, phase did" ) local sceneName = composer.getSceneName( "previous" ) if sceneName ~= nil then composer.removeScene( sceneName, true ) end end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if "will" == phase then print( "1: hide event, phase will" ) -- cancel timer if isChannel1Playing == true then timer.cancel( changeTimer ); changeTimer = nil end -- remove audio audio.stop() audio.dispose( audioSound ) end end function scene:destroy( event ) print( "((destroying scene 1's view))" ) local sceneGroup = self.view end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

What is line 141?

That error generally means the object has already been removed or it was never created in the first place or it’s out of scope.

Rob

LIne 141 is the bold one below

function changeImage() if myCurrentImageC2 ~= nil and isChannel1Playing == true then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 2 sceneGroup:insert( myCurrentImageC2 ) end end 

I changed the btn function which is where I press the back button to leave the scene and go to another one.

Seems that even though I have set the audio to dispose and the timers to cancel when I leave the scene that it keeps going and tries to change the image in the changeImage Function - once I start the audio the timer starts counting with a delay to go to that function, I leave before it gets there but then it continues in the background and gets to that function but the object is gone. By setting the isPlaying to false when I click back it doesnt get past the if condition at the start.

Seems to have fixed it but im wondering why when Ieave the scene it continues with timer even though it should be set to nil?

You never change isChannel1Playing to true once you start playing the audio.

Rob

I thought this was a read value that returns if the channel is playing? I expected it to return true automatically once the audio is playing…is this not the case?

https://docs.coronalabs.com/api/library/audio/isChannelPlaying.html

Right, you called it once at the top of the scene. It runs exactly once. Code in the main chunk of the scene only executes once until the scene is un-requried and reloaded. So if you don’t remove the scene before going back it won’t run that code again.

But in your scene, your button starts the music, it’s best to set the flag there.

Rob

Cool, gotcha.

Thanks Rob

So I changed my code a bit and added in some extra functionality so that when automatic part takes place with the audio playing i remove the arrows so the user can mess with it. Then when the audio finishes I put the arrows back in so they can manually edit it.

When I leave the scene I am getting an error though in the changeImage function about the removeSelf()

Line: 141
Attempt to call method ‘removeSelf’ (a nil value)

Any ideas what the reason is?

print("location1") local leftSide = display.screenOriginX; local rightSide = display.contentWidth-display.screenOriginX; local topSide = display.screenOriginY; local bottomSide = display.contentHeight-display.screenOriginY; --------------------------------------------------------------------------------------- local composer = require "composer" local scene = composer.newScene() local widget = require "widget" math.randomseed(os.time()) -- Called when the scene's view does not exist: function scene:create( event ) local sceneGroup = self.view local audioSound = audio.loadSound("audio/cork/2\_dauntsSquare.mp3") local isChannel1Playing = audio.isChannelPlaying( 1 ) local function btnTouch( event ) if event.phase == "ended" then print ("button pressed") composer.gotoScene(event.target.btnDestination, {time=250, effect="crossFade"}) return true end end local function myAudio( event ) if event.phase == "ended" then if isChannel1Playing == false then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) arrowLeft.isVisible = false arrowRight.isVisible = false event.target.audioChannel = audio.play(audioSound,{ channel=1,onComplete = messageMe}) isChannel1Playing = true changeTimer = timer.performWithDelay( 23000, changeImage ) end return true end end function messageMe( event ) if ( event.completed ) then arrowLeft.isVisible = true arrowRight.isVisible = true myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) print("audio finished") isChannel1Playing = false end end local bg = display.newImageRect("images/bg\_legacy.jpg", 360, 568) bg.x = display.contentCenterX bg.y = display.contentCenterY sceneGroup:insert( bg ) -- code to slide through locations -- myImagesC2 = {"images/Cork/2a.png", "images/Cork/2b.png" } -- name of images currentImageIndex = 1 -- this is index to track your current image -- display the first image myCurrentImageC2 = display.newImageRect( myImagesC2[1],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 1 sceneGroup:insert( myCurrentImageC2 ) -- Function to handle back and forward buttons local function handleButtonEvent( event ) if ( "ended" == event.phase ) then if event.target.id == "back" and currentImageIndex \> 1 then print( "Back" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex - 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex - 1 myCurrentImageC2.currentImageIndex = currentImageIndex elseif event.target.id == "fwd" and currentImageIndex \< 2 then print( "fwd" ) myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImage( myImagesC2[currentImageIndex + 1]) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 sceneGroup:insert( myCurrentImageC2 ) arrowLeft:toFront() arrowRight:toFront() currentImageIndex = currentImageIndex + 1 myCurrentImageC2.currentImageIndex = currentImageIndex end return true end end function changeImage() if myCurrentImageC2 ~= nil and isChannel1Playing == true then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 2 sceneGroup:insert( myCurrentImageC2 ) end end -- Create a ScrollView local scrollView = widget.newScrollView { left = 0, top = display.contentCenterY+40, width = display.contentWidth, height = 150, topPadding = 10, bottomPadding = 20, id = "onBottom", horizontalScrollDisabled = true, verticalScrollDisabled = false, listener = scrollListener, hideBackground = true, } --Create a large text string local myText =[[Their eldest child, Mary, was born on 19th January, 1787 in the house in Daunt's Square. Historically, Cork was built on marshland and at that time had a network of canals, bridges and narrow laneways criss-crossing the city from the North Gate Bridge to the South Gate Bridge. Mary's father was a doctor and he owned a pharmacy trading under the name of Aikenhead & Dupont. Over 80,000 people lived in the crammed laneways around Cork city where clean water was not readily available. The living conditions and health of the poor in particular were appalling.]] --Create a text object containing the large text string and insert it into the scrollView local myText = display.newText( myText, display.contentCenterX, 0, 300, 0, "Gotham-Book", 14) myText:setFillColor( 0 ) myText:setTextColor( 0, 0, 0 ) myText.anchorY = 0.0 -- Top --------------------------------myText:setReferencePoint( display.TopCenterReferencePoint ) -- myText.y = titleText.y + titleText.contentHeight + 10 scrollView:insert( myText ) sceneGroup:insert( scrollView ) local backBtn = display.newImageRect("images/Cork/daunts.jpg", 360, 40) backBtn.x = display.contentCenterX backBtn.y = display.screenOriginY+20; backBtn.btnDestination = "cork" backBtn:addEventListener( "touch", btnTouch ) sceneGroup:insert( backBtn ) local audioBtn = display.newImageRect("images/playAudioVisual.jpg", 360, 40) audioBtn.x = display.contentCenterX audioBtn.y = bottomSide -20 audioBtn:addEventListener( "touch", myAudio ) audioBtn:toFront( ) sceneGroup:insert( audioBtn ) arrowLeft = display.newImageRect("images/arrowLeftDark.png", 12, 21) arrowLeft.x = display.screenOriginX+20 arrowLeft.y = display.contentCenterY-80 arrowLeft:toFront( ) arrowLeft.id = "back" arrowLeft:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowLeft ) arrowRight = display.newImageRect("images/arrowRightDark.png", 12, 21) arrowRight.x = display.contentWidth-display.screenOriginX -20; arrowRight.y = display.contentCenterY-80 arrowRight:toFront( ) arrowRight.id = "fwd" arrowRight:addEventListener( "touch", handleButtonEvent ) sceneGroup:insert( arrowRight ) local function moveToFront( ) arrowRight:toFront( ) arrowLeft:toFront( ) end end function scene:show( event ) local sceneGroup = self.view local phase = event.phase if "did" == phase then print( "1: show event, phase did" ) local sceneName = composer.getSceneName( "previous" ) if sceneName ~= nil then composer.removeScene( sceneName, true ) end end end function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if "will" == phase then print( "1: hide event, phase will" ) -- cancel timer if isChannel1Playing == true then timer.cancel( changeTimer ); changeTimer = nil end -- remove audio audio.stop() audio.dispose( audioSound ) end end function scene:destroy( event ) print( "((destroying scene 1's view))" ) local sceneGroup = self.view end --------------------------------------------------------------------------------- -- Listener setup scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) --------------------------------------------------------------------------------- return scene

What is line 141?

That error generally means the object has already been removed or it was never created in the first place or it’s out of scope.

Rob

LIne 141 is the bold one below

function changeImage() if myCurrentImageC2 ~= nil and isChannel1Playing == true then myCurrentImageC2:removeSelf() myCurrentImageC2 = nil myCurrentImageC2 = display.newImageRect( myImagesC2[2],240,159) myCurrentImageC2.x = display.contentCenterX myCurrentImageC2.y = display.contentCenterY-70 myCurrentImageC2.currentImageIndex = 2 sceneGroup:insert( myCurrentImageC2 ) end end 

I changed the btn function which is where I press the back button to leave the scene and go to another one.

Seems that even though I have set the audio to dispose and the timers to cancel when I leave the scene that it keeps going and tries to change the image in the changeImage Function - once I start the audio the timer starts counting with a delay to go to that function, I leave before it gets there but then it continues in the background and gets to that function but the object is gone. By setting the isPlaying to false when I click back it doesnt get past the if condition at the start.

Seems to have fixed it but im wondering why when Ieave the scene it continues with timer even though it should be set to nil?