2

我正在使用 Corona SDK 编写 iOS 应用程序。该应用程序已完成,但我发现了故事板的错误。打开几个不同的故事板场景并返回到这个场景后,我收到一个错误(见下文)。这似乎是随机的,我可以毫无问题地返回现场 4 或 5 次,但其他时候它可能会在我第一次返回时出现。我只能假设这取决于 Corona 对场景的内部处理,当内存使用量达到一定水平时,它会清除场景。

我收到的错误是:

Runtime error
    /Users/**/contact.lua:124: attempt to call method 'insert' (a nil value)
stack traceback:
    [C]: in function 'insert'
    /Users/**/contact.lua:124: in function 'renderPage'
    /Users/**/contact.lua:179: in function </Users/**/contact.lua:166>

产生此错误的代码如下。请注意,此代码在第一次打开时运行良好,并且在出现错误之前需要随机数次场景更改。

-----------------------------------------------------------------------------------------
--
-- contact.lua
--
-----------------------------------------------------------------------------------------

local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
local widget = require( "widget" )
local tableView = require( "tableViewXL" )

-----------------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
-- 
-- NOTE: Code outside of listener functions (below) will only be executed once,
--       unless storyboard.removeScene() is called.
-- 
-----------------------------------------------------------------------------------------

-- Called when the scene's view does not exist:
function scene:createScene( event )
    local group = self.view

    local function openMenu()
        transition.to( menu, { x = 0, time=600, transition=easing.outQuad } )
        this_window = 'contact'
        native.cancelWebPopup()
    end

    local openBtn = ui.newButton{
        defaultSrc = 'images/menu.png',
        defaultX = 29,
        defaultY = 29,
        overSrc = 'images/menu.png',
        overX = 29,
        overY = 29,
        overAlpha = .5,
        onEvent = openMenu,
        text = "",
        size = 14,
        textColor = { 138, 173, 189, 255 },
        font = system.nativeFont,
        emboss = false,
        id = "Button",
    }
    openBtn.x = 28; openBtn.y = 28



    -- add background and logout button
    local bg = display.newImageRect( "images/background.png", 320, 480 )
    bg:setReferencePoint( display.TopLeftReferencePoint )
    bg.x = 0; bg.y = 0;

    -- Date
    local date = txt.newEmbossed(os.date("%d/%m/%y"), 10, 60, native.systemFontBold, 12)
    date:setTextColor( 55, 96, 127 )    -- blue
    date:setReferencePoint( display.CenterReferencePoint )
    date.x = 280
    date.y = 84

    -- Title
    local title = txt.new( "Contact", 17, 72, 'Georgia', 20 )
    title:setTextColor( 71, 24, 76 )

    -- Called when the API is able to return user info (fb page, twitter, etc)
    function renderPage( data )

        local textAddress = txt.new( data.address, 17, 120, native.systemFont, 14, display.TopLeftReferencePoint, 300, 200 )
        textAddress:setTextColor( 0, 0, 0 )     

        local phoneBar = display.newImageRect( "images/contact/phoneBar.png", 296, 24 )
        phoneBar.x = (display.contentWidth * 0.5); phoneBar.y = 230
        local phoneText = txt.new( data.phone, 20, 222, native.systemFont, 12, display.TopLeftReferencePoint )
        phoneText:setTextColor( 70, 24, 72 )

        local emailBar = display.newImageRect( "images/contact/emailBar.png", 296, 24 )
        emailBar.x = (display.contentWidth * 0.5); emailBar.y = 260
        local emailText = txt.new( data.email, 20, 252, native.systemFont, 12, display.TopLeftReferencePoint )
        emailText:setTextColor( 70, 24, 72 )

        local twitterBar = display.newImageRect( "images/contact/twitterBar.png", 296, 24 )
        twitterBar.x = (display.contentWidth * 0.5); twitterBar.y = 290
        local twitterText = txt.new( 'Twitter - @'.. data.twitter, 20, 282, native.systemFont, 12, display.TopLeftReferencePoint )
        twitterText:setTextColor( 70, 24, 72 )

        local facebookBar = display.newImageRect( "images/contact/facebookBar.png", 296, 24 )
        facebookBar.x = (display.contentWidth * 0.5); facebookBar.y = 320
        local facebookText = txt.new( 'Facebook', 20, 312, native.systemFont, 12, display.TopLeftReferencePoint )
        facebookText:setTextColor( 70, 24, 72 )

        local function phoneTouch( event )
            if ( event.phase == "ended" ) then
                system.openURL( "tel:".. data.phone )
            end
        end
        local function emailTouch( event )
            if ( event.phase == "ended" ) then
                system.openURL( "mailto:".. data.email )
            end
        end
        local function twitterTouch( event )
            if ( event.phase == "ended" ) then
                system.openURL( "https://twitter.com/intent/user?screen_name=".. data.twitter )
            end
        end
        local function facebookTouch( event )
            if ( event.phase == "ended" ) then
                system.openURL( "fb://profile/".. data.facebook )
            end
        end

        phoneBar:addEventListener( 'touch', phoneTouch )
        phoneText:addEventListener( 'touch', phoneTouch )
        emailBar:addEventListener( 'touch', emailTouch )
        emailText:addEventListener( 'touch', emailTouch )
        twitterBar:addEventListener( 'touch', twitterTouch )
        twitterText:addEventListener( 'touch', twitterTouch )
        facebookBar:addEventListener( 'touch', facebookTouch )
        facebookText:addEventListener( 'touch', facebookTouch )

        print ( textAddress )

        group:insert( textAddress )     
        group:insert( phoneBar )        
        group:insert( phoneText )       
        group:insert( emailBar )        
        group:insert( emailText )       
        group:insert( twitterBar )      
        group:insert( twitterText )     
        group:insert( facebookBar )
        group:insert( facebookText )

        phoneText:toFront()
        emailText:toFront()
        twitterText:toFront()
        facebookText:toFront()

        -- Add the map
        -- Load map template from a file
        local path = system.pathForFile( "map_template.html", system.ResourceDirectory )

        local file = io.open( path, "r" )

        local mapTemplate = file:read( "*a" )
        io.close( file )
        -- Add in our address and write to another file
        address = data.address1
        if(data.address2 == '' and data.address2 ~= '') then address = address .. ', ' .. data.address2 end
        if(data.citytown == '' and data.citytown ~= '') then address = address .. ', ' .. data.citytown end
        if(data.county == '' and data.county ~= '') then address = address .. ', ' .. data.county end
        if(data.postcode == '' and data.postcode ~= '') then address = address .. ', ' .. data.postcode end

        mapTemplate = string.gsub( mapTemplate, "||ADDRESS||", address )
        -- Now save it to a local file
        local path = system.pathForFile( "map.html", system.DocumentsDirectory )
        local file = io.open( path, "w" )
        file:write( mapTemplate )
        io.close( file )

        local options = { hasBackground=false, baseUrl=system.DocumentsDirectory, urlRequest=listener }
        native.showWebPopup( 0, 345, display.contentWidth, 130, "map.html", options )
    end


    function api.networkListener( event )
        native.setActivityIndicator( false )
        if ( event.isError ) then
            native.showAlert( "Error", "Sorry, there was a problem communicating with the server.", {"Ok"} )
        else
            json = require "json"
            local response = json.decode( event.response )
            if(response.error) then
                native.showAlert( "Error", response.error, {"Ok"} )

            else                

                data = response
                renderPage( data )
            end
        end
        return event.response
    end

    native.setActivityIndicator( true )
    api.request( 'users/me', "GET" )


    -- all objects must be added to group (e.g. self.view)
    group:insert( bg )
    group:insert( date )
    group:insert( title )
    group:insert( openBtn )

end

-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
    local group = self.view

end

-- Called when scene is about to move offscreen:
function scene:exitScene( event )
    local group = self.view

    -- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.)
    native.cancelWebPopup()
end

-- If scene's view is removed, scene:destroyScene() will be called just prior to:
function scene:destroyScene( event )
    local group = self.view

    -- INSERT code here (e.g. remove listeners, remove widgets, save state variables, etc.)
    native.cancelWebPopup()

end

-----------------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
-----------------------------------------------------------------------------------------

-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener( "createScene", scene )

-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )

-- "exitScene" event is dispatched whenever before next scene's transition begins
scene:addEventListener( "exitScene", scene )

-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )

-----------------------------------------------------------------------------------------

return scene

当另一个场景打开时,我尝试清除这个场景。打印时grouptextAddress两者都是表格,正如预期的那样。

4

1 回答 1

0

我的猜测是在renderPage调用之间group变量的值(它指向self.view第一次调用时的保存对象)发生变化。您提到您正在打印grouptextAddress. 你也可以打印group.insert价值吗?

    print ( textAddress, group, group.insert )

    group:insert( textAddress ) <-- line 124

以下片段将触发相同的错误:

local scene = { view = { insert = function(...) print(...) end }}

function scene:createScene( event )
  local group = self.view

  function renderPage( data )
    group:insert( 'foo ' .. data )     
  end
end

scene:createScene()
renderPage(11)
renderPage(12)

scene.view.insert = nil
renderPage(13)

请注意,renderPage每次创建新场景时都会重新创建,并且 newrenderPage指的group是新创建的场景中的变量(可能是也可能不是您想要的)。

于 2012-09-19T15:58:07.767 回答