http://www.massivepoint.com/airsqltest/AIRSQL.zip
以下是包装类的代码:
如果你向下看sqlRequest类中的第51行,你会看到注释掉的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,true); _statement.addEventListener(sqlErrorEvent.ERROR,handleError,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是函数的本地函数,并在函数返回时变为不可缓存.这使它可收藏.我想在AIR运行时必须有一些代码,当涉及到sql连接时,它会更加积极地收集垃圾.因为通常情况下,你不会将ref存储到你的对象中(至少在基于web的环境中,根据我的经验;这是这类代码中的一个错误;然而你只需要在糟糕的一天中体验它).
setTimeout掩盖了这个问题(或者几乎解决了它,尽管是以一种无意的方式),因为setTimeout函数在内部使用了Timer.不收集运行计时器.因此,计时器处于活动状态并且具有对sqlRequest实例的引用,这使得它可以进行访问,因此不适合收集.如果您的数据库调用花费的时间超过了超时,那么您将恢复相同的状态.
要解决此问题,请将ref存储到对象并在完成后正确处理.
编辑
另一个选项,如果你不想改变调用代码的方式,则在调用期间将一个ref存储在类范围(即静态)字典中(该字典不应使用弱引用键原因很明显).
您正在为方法添加隐藏的副作用,这通常不是良好设计的标志,但只要在完成对DB的调用(无论是否成功)时将其删除,您就是安全的,所以我认为问题更多的是风格而不是其他任何东西.
我的意思是这样的:
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]; } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。