AIR Sqlite:SQLEvent.RESULT没有触发,但语句正在正确执行
好吧,它看起来像我偶然发现奇怪的时间问题...我做了一个快速的SQL包装类执行SQL语句。但是,在调用.execute()之后,SQLEvent.RESULT事件永远不会被触发,但DB中的新条目将按照它的原样创建。真正非常奇怪的是,如果我在调用execute()后立即调用setTimeout(),事件会像预期的那样触发。我希望我在这里错过了一些非常明显的东西......下面是一个示例空气应用程序的链接: http://www.massivepoint.com/airsqltest/AIRSQL.zipAIR Sqlite:SQLEvent.RESULT没有触发,但语句正在正确执行
这里是代码来包装类:
,如果你在第51行中SQLREQUEST类往下看,你会看到注释掉setTimeout()方法。为了使所有的工作,只是取消注释该行..但对我来说这没有任何意义...
任何人有任何想法?我完全难住在这里...
package com.jac.sqlite
{//Package
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.EventDispatcher;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import flash.utils.setTimeout;
public class SQLRequest extends EventDispatcher
{//SQLRequest Class
private var _callback:Function;
private var _dbConn:SQLConnection;
private var _query:String;
private var _params:Object;
private var _statement:SQLStatement;
public function SQLRequest(callback:Function, connection:SQLConnection, query:String, parameters:Object=null):void
{//SQLRequest
trace("Creating new SQL Request");
_callback = callback;
_dbConn = connection;
_query = query;
_params = parameters;
_statement = new SQLStatement();
_statement.sqlConnection = _dbConn;
_statement.text = _query;
if (_params != null)
{//assign
for (var param:String in _params)
{//params
trace("Setting Param: " + param + " to: " + _params[param]);
_statement.parameters[param] = _params[param];
}//params
}//assign
//setup events
_statement.addEventListener(SQLEvent.RESULT, handleResult, false, 0, true);
_statement.addEventListener(SQLErrorEvent.ERROR, handleError, false, 0, true);
}//SQLRequest
public function startLoad():void
{//execute
_statement.execute();
//setTimeout(handleTimeOut, 10000);
}//execute
//TEMP
private function handleTimeOut():void
{//handleTimeOut
trace("Executing: " + _statement.executing + "/" + executing);
}//handleTimeOut
private function handleResult(e:SQLEvent):void
{//handleResult
trace("Good SQL Request");
_callback(e);
dispatchEvent(e);
}//handleResult
private function handleError(e:SQLErrorEvent):void
{//handleError
trace("SQL Error: " + e.errorID + ": " + e.error);
//dispatchEvent(e);
}//handleError
public function get executing():Boolean
{//get executing
return _statement.executing;
}//get executing
public function get query():String { return _query; }
public function get statement():SQLStatement { return _statement; }
}//SQLRequest Class
}//Package
我想你在这里错过的是垃圾收集。
未测试您的代码,但这肯定是问题的根源。
var sqlReq:SQLRequest = new SQLRequest(handleResult, _dbConn, sql);
sqlReq.startLoad();
参考sqlReq
是本地的功能,并成为unreacheable当函数返回。这使得它是可收集的。我想在AIR运行时必须有一些代码,在涉及sql连接时更积极地收集垃圾。因为通常情况下,你不会将ref存储在你的对象中(至少在我的经验中,至少在一个基于web的环境中;这是这样的代码中的一个错误;不过,你只需要在糟糕的一天体验它)。
的setTimeout
掩盖这个问题(或几乎解决了它,虽然在一个意想不到的方式),因为setTimeout
函数内部使用一个Timer
。运行计时器不收集。所以,计时器仍然活着并踢,并且对您的SQLRequest
实例有一个参考,这使得它可以重新获得,因此不适合收集。如果您的数据库调用需要比超时更长的时间,则会恢复相同的情况。
为了解决这个问题,请将ref存储到对象中,并在完成后妥善处置它。
编辑
另一种选择,如果你不想改变你调用代码的工作方式,是存储裁判实例在类范围(即静态)字典的持续时间这个电话(这个字典并不是使用弱引用键的原因很明显)。
你正在为你的方法增加一个隐藏的副作用,这通常不是一个好设计的标志,但只要你在调用数据库的时候删除它(不管它是否成功),你'很安全,所以我认为问题比其他任何方式都更具风格。
我的意思是这样的:
private static var _dict:Dictionary = new Dictionary();
public function startLoad():void
{//execute
_statement.execute();
// add a self reference to dict so the instance won't be collected
// do this in the last line, so if we have an exception in execute, this
// code will not run (or add a try/catch if you want, but this is simpler
// and cleaner, IMO
addToDict();
}//execute
private function handleResult(e:SQLEvent):void
{//handleResult
// remove the self reference before running any other code
// (again, this is in case the code that follows throws)
removeFromDict();
trace("Good SQL Request");
_callback(e);
dispatchEvent(e);
}//handleResult
private function handleError(e:SQLErrorEvent):void
{//handleError
// same comment as handleResult
removeFromDict();
trace("SQL Error: " + e.errorID + ": " + e.error);
//dispatchEvent(e);
}//handleError
private function addToDict():void {
_dict[this] = true;
}
private function removeFromDict():void {
if(_dict[this]) {
delete _dict[this];
}
}
啊哈废话,就是这样......非常感谢你指出了这一点! – Jake 2010-07-26 03:09:53