2

私はCoronaSDKを使用してiOSアプリを作成しています。アプリは完成しましたが、ストーリーボードにバグが見つかりました。いくつかの異なるストーリーボードシーンを開いてこの1つのシーンに戻った後、エラーが発生します(以下を参照)。ランダムに見えるので、問題なく4〜5回シーンに戻ることができますが、最初に戻ったときに表示される場合もあります。これは、メモリ使用量が特定のレベルに達したときにシーンをパージする、コロナのシーンの内部処理にのみ起因すると推測できます。

私が受け取っているエラーは次のとおりです。

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

別のシーンを開いたときにこのシーンをパージしてみました。予想通り、印刷groupまたはtextAddress両方がテーブルの場合。

4

1 に答える 1

0

私の推測では、変数の値 (最初に呼び出されたときのように保存オブジェクトを指す) が変化するrenderPage呼び出しの間にあると思います。あなたはあなたが印刷していると述べました. 値も印刷できますか?groupself.viewgrouptextAddressgroup.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新しいシーンを作成するたびに再作成し、新しいシーンは新しく作成されたシーンrenderPageの変数を参照することに注意してくださいgroup(これは必要な場合とそうでない場合があります)。

于 2012-09-19T15:58:07.767 に答える