博客公告(点击显示/隐藏)| 今日心情:转眼间又快踏入新的一年~新年新气象~
2008-08-20 23:41:27
敬告所有想在我博客刷广告的朋友先看一下这篇文章小S吧今天你来了吗?更新速度:每周2-3篇以上!在俺博客看到有用的东西,学习了之后,记得回访带点人气哦 ^_^ 嘿嘿!
欢迎跟俺交换友情链接啊。。留言,直接QQ等联系我都行啊
转载本博客文章请注明:来源小S吧——sunbright博客,链接地址:http://www.xiaos8.com
2010
2-9
今年要去老婆老家过年,因此没啥机会上网了,所以在这提前祝大家新年快乐
如果你在过年期间,看到了这封帖子,并且还回帖了
这么意味着你2010年的运势将前程似锦,步步高升!工作的,节节高升!
上学的,门门百分!
做生意的,财源广进!
已经赚大钱的,恭喜发财,红包拿来!
如果你在过年期间,看到了这封帖子,并且还回帖了
这么意味着你2010年的运势将前程似锦,步步高升!工作的,节节高升!
上学的,门门百分!
做生意的,财源广进!
已经赚大钱的,恭喜发财,红包拿来!
2010
2-7
今天依旧如故玩着DNF消遣,但突然一句世界频道发出来的话,把我震惊了!
应该不是九城派人去DNF这样拉人的吧?但是又有什么理由能让我们相信这是个人行为呢?
九城失去魔兽,难道真的输不起吗?
我去体验过《名将三国》,当然不是冲着那Q币去的,玩了三个号每次换新号的原因都是卡在了新手任务中,无法进行下去,所以就没玩了。
过多的评价我不说了,我不是枪手也不是写软文,所以也不说太多了,只是把我看到的讲出来罢了~
![]() |
应该不是九城派人去DNF这样拉人的吧?但是又有什么理由能让我们相信这是个人行为呢?
九城失去魔兽,难道真的输不起吗?
我去体验过《名将三国》,当然不是冲着那Q币去的,玩了三个号每次换新号的原因都是卡在了新手任务中,无法进行下去,所以就没玩了。
过多的评价我不说了,我不是枪手也不是写软文,所以也不说太多了,只是把我看到的讲出来罢了~
2010
1-29
在公司门口和策划部门主管合影,值得一提的我们公司与CCTV合作,举办了“希望之星”英语风采大赛
“希望英语”唯智学园专区地址:http://wiz.cctvoe.com
我们公司产品唯智学园官方主页:http://www.wizworldonline.com年会现场,还有很多同事没到额 - -!
哥俩好啊~~这是我老家的兄弟,有幸现在在同一个公司,我们是从小长大的好兄弟~
我的吃像就不敢拍了,拍个食物来勾引一下大家吧~
我跟Rick.Goodman的合影,Rick是我们公司的副总裁兼首席产品官,当然他还有另外一个很好很强大的身份:《帝国时代》的总策划,百度百科地址:http://baike.baidu.com/view/3183300.html
![]() |
“希望英语”唯智学园专区地址:http://wiz.cctvoe.com
我们公司产品唯智学园官方主页:http://www.wizworldonline.com年会现场,还有很多同事没到额 - -!
![]() |
![]() |
![]() |
![]() |
2010
1-26
引言
在2010年1月24日在上海举办的Flash开发者交流会中,我曾经在会场上讲了Tween,URLLoader等类,会因为使用弱引用侦听而导致错误,是什么原因出错呢?下面讲的就是错误的根源,也算是对于我那天所讲,做一个全面的补充。(另外:感谢李正民同学让我了解了"引用计数"这个专业词)
点击上方的黑色小按钮,点一次发现效果还不错,那么你在开始有间隔的狂点这个小按钮,点的次数多了,时间长了,BUG就出现了,会发现有些动画卡住了,显示对象有时候不会运动到四周。
下面的代码就是这个Flash的源码,看过了BUG后,接下来谁能在代码中发现这个BUG是如何引发的呢?
package
{
import fl.transitions.Tween;
import fl.transitions.easing.Bounce;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.MouseEvent; public class TestShow extends Sprite
{
[Embed (source="1.jpg")]
private var Pic:Class;
private var btn:Sprite;
private var centerX:int;
private var centerY:int;
public function TestShow()
{
init();
}
//初始化
private function init():void{
centerX = stage.stageWidth / 2;
centerY = stage.stageHeight / 2;
btn = new Sprite;
btn.graphics.beginFill(0,0.5);
btn.graphics.drawRect(centerX - 10,0,20,10);
btn.graphics.endFill();
btn.buttonMode = true;
stage.addChild(btn);
btn.addEventListener(MouseEvent.CLICK,clickHandle);
}
//点击创建
private function clickHandle(e:MouseEvent):void{
var width:int = stage.stageWidth;
var height:int = stage.stageHeight;
for(var i:int = 0; i <= 8; i ++){
var x:int = centerX,y:int = centerY;
if(i == 4) continue;
if(i % 3 == 0) x = 0;
else if(i % 3 == 2) x = width;
if(i < 3) y = 0;
else if(i > 5) y = height;
create(x,y);
}
}
//创建一个
private function create(x:int,y:int):void{
var spr:Sprite = new Sprite;
var pic:Bitmap = new Pic;
pic.x = - pic.width / 2;
pic.y = - pic.height / 2;
spr.addChild(pic);
spr.x = centerX;
spr.y = centerY;
setAnimation(spr,x,y);
addChild(spr);
}
//创建动画
private function setAnimation(spr:Sprite,x:int,y:int):void{
var tweenX:Tween = new Tween(spr,"x",Bounce.easeOut,spr.x,x,50);
var tweenY:Tween = new Tween(spr,"y",Bounce.easeOut,spr.y,y,50);
}
}
}
看到这儿,聪明的开发者不知道你有没有思考过呢?但下面来看看我分析的原因:{
import fl.transitions.Tween;
import fl.transitions.easing.Bounce;
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.MouseEvent; public class TestShow extends Sprite
{
[Embed (source="1.jpg")]
private var Pic:Class;
private var btn:Sprite;
private var centerX:int;
private var centerY:int;
public function TestShow()
{
init();
}
//初始化
private function init():void{
centerX = stage.stageWidth / 2;
centerY = stage.stageHeight / 2;
btn = new Sprite;
btn.graphics.beginFill(0,0.5);
btn.graphics.drawRect(centerX - 10,0,20,10);
btn.graphics.endFill();
btn.buttonMode = true;
stage.addChild(btn);
btn.addEventListener(MouseEvent.CLICK,clickHandle);
}
//点击创建
private function clickHandle(e:MouseEvent):void{
var width:int = stage.stageWidth;
var height:int = stage.stageHeight;
for(var i:int = 0; i <= 8; i ++){
var x:int = centerX,y:int = centerY;
if(i == 4) continue;
if(i % 3 == 0) x = 0;
else if(i % 3 == 2) x = width;
if(i < 3) y = 0;
else if(i > 5) y = height;
create(x,y);
}
}
//创建一个
private function create(x:int,y:int):void{
var spr:Sprite = new Sprite;
var pic:Bitmap = new Pic;
pic.x = - pic.width / 2;
pic.y = - pic.height / 2;
spr.addChild(pic);
spr.x = centerX;
spr.y = centerY;
setAnimation(spr,x,y);
addChild(spr);
}
//创建动画
private function setAnimation(spr:Sprite,x:int,y:int):void{
var tweenX:Tween = new Tween(spr,"x",Bounce.easeOut,spr.x,x,50);
var tweenY:Tween = new Tween(spr,"y",Bounce.easeOut,spr.y,y,50);
}
}
}
首先我们回顾一些知识点:
Flash的自动内存回收分为两个方式,1是是否引用计数为0,2是是否存在Stage中。
我们现在来关心下第一个方式:
当一次强引用,该对象的引用计数加1;
当一次弱引用,该对象的引用计数不加;
当强引用侦听事件,引用计数加1,弱引用不加;
我们现在来关心下第一个方式:
当一次强引用,该对象的引用计数加1;
当一次弱引用,该对象的引用计数不加;
当强引用侦听事件,引用计数加1,弱引用不加;
当然这里有很多种情况,我这列举两条:
1、事件侦听时,addEventListener的第5个参数,为true表示弱引用侦听,为false反之(默认是false,即强引用侦听);
2、在Function中的变量引用,虽然不能说他就是弱引用,但Function执行完毕后,该引用计数其实并没有加1
比如以下Code,就算调用了func,Sprite实例对象的引用计数还是只有1
private var spr:Sprite = new Sprite;
private function func():void{
var a:Sprite = spr;
}
我们现在来看这段代码:private function func():void{
var a:Sprite = spr;
}
//创建动画
private function setAnimation(spr:Sprite,x:int,y:int):void{
var tweenX:Tween = new Tween(spr,"x",Bounce.easeOut,spr.x,x,50);
var tweenY:Tween = new Tween(spr,"y",Bounce.easeOut,spr.y,y,50);
}
从这段代码不难理解,两个new Tween分别创建了两个Tween实例,并分别被tweenX和tweenY引用,但tweenX,tweenY它是局部引用,当这个Function执行完后,创建的两个Tween实例引用计数就是0,那么这时候如果启动了自动内存回收,理论上Tween类的两个实例都会被回收掉,结果也正是如此!所以上面问题出现了!private function setAnimation(spr:Sprite,x:int,y:int):void{
var tweenX:Tween = new Tween(spr,"x",Bounce.easeOut,spr.x,x,50);
var tweenY:Tween = new Tween(spr,"y",Bounce.easeOut,spr.y,y,50);
}
怎么解决呢?
首先,一个好好的动画在这儿它为什么会被自动回收掉呢?理论上动画的过程是不会被回收的!
我们来看看ADOBE官方Tween类中的一段代码:
protected function startEnterFrame():void
{
if (isNaN(this._fps))
{
// original frame rate dependent way
_mc.addEventListener(Event.ENTER_FRAME, this.onEnterFrame, false, 0, true);
}
else
{
// custom frame rate
var milliseconds:Number = 1000 / this._fps;
this._timer.delay = milliseconds;
this._timer.addEventListener(TimerEvent.TIMER, this.timerHandler, false, 0, true);
this._timer.start();
}
this.isPlaying = true;
}
大家可以发现,addEventListener的第5个参数是使用的弱引用侦听,这也表示如果Tween类在外部没有引用计数,而内部也没引用计数,OK,内存回收时,它自然被干掉了!{
if (isNaN(this._fps))
{
// original frame rate dependent way
_mc.addEventListener(Event.ENTER_FRAME, this.onEnterFrame, false, 0, true);
}
else
{
// custom frame rate
var milliseconds:Number = 1000 / this._fps;
this._timer.delay = milliseconds;
this._timer.addEventListener(TimerEvent.TIMER, this.timerHandler, false, 0, true);
this._timer.start();
}
this.isPlaying = true;
}
那么如何解决呢?
1、将这个地方的侦听改成强引用侦听,这个问题这样的确解决了,但是Tween引用计数加1了,因此随后你也要记得将它移除,比如加个clear的方法,来移除事件侦听。否则会内存泄露!
2、将Tween实例在类中全局引用,比如push到某个类对象数组中,但同样的问题记得用完要删除!
说了这么多,总感觉这个知识点还没说的很完整,如果谁没看懂,或者有问题问的,希望能跟帖询问,我会一一解答的!另外URLLoader等类也是存在同样的问题,如果使用弱引用侦听,而没有保存到类全局变量,如果在加载的过程中,突然碰到内存自动回收,那么这个对象也就不复存在,并且会报错,说数据不完整之类的
最后总结:
1、关于内存管理:一定是创建了就记得销毁,一定是侦听了就记得移除!不要太依靠弱引用来帮你做内存管理!
2、关于写代码习惯:有创建,就要有销毁!有addEventListener,就要有removeEventListener!
3、强弱引用是个好东西,但一定要弄清楚它的工作原理!当然任何知识点都要了解透彻!关于这个文章,大家也可以到天地会论坛中进行讨论:http://flash.9ria.com/thread-44077-1-1.html
2010
1-24
参加这次活动,又认识了许多新朋友,这次讲的东西都很好。
前几场的同僚讲的,比如从其他语言的角度来剖析Flash的对象;还有ADOBE在内存自动回收是如何去工作;等等,讲的非常好。
虽然以前是了解这些的,但现在感觉更深层次了解了这些内部的机制。
感谢主办方给我们带来这么好的一次聚会~
因为今天我在会场无心插柳讲出了我博客地址,那么如果谁愿意跟我交换友情连接的可以跟我说,咱们可以多交流交流~毕竟Flash未来良好的发展趋势,还是得靠我们一步步共同去挖掘。
因为我公司是全封闭式开发,所有1年多来已经习惯不开IM软件(当然除了QQ,也包括MSN等主流通讯软件),所以今天在会场上有人问及我QQ还有MSN什么的,很不好意思我是真的很久没上过了,不过大家想找我可以博客留言,如果是有问题在博客留言,我承诺一定会在最短时间解答你的问题,当然我也不是万能的,涉及到框架问题我帮不了你,我不是很喜欢用框架,虽然我会去研究ASWing,PV3D等主流框架的底层结构,但从来没用过,正如今天会场上有位帅哥讲的一样,简单才是最好的。
另外大家也可以发电子邮件找我:sunkill@163.com(不是很频繁看邮箱,如果回信速度慢了,请多见谅)
当然硬说没QQ,大家也不会相信,我QQ是36806312,不过真的很久没上了,不过最近可能会上一下,当然是因为这次会场的缘故拉
前几场的同僚讲的,比如从其他语言的角度来剖析Flash的对象;还有ADOBE在内存自动回收是如何去工作;等等,讲的非常好。
虽然以前是了解这些的,但现在感觉更深层次了解了这些内部的机制。
感谢主办方给我们带来这么好的一次聚会~
因为今天我在会场无心插柳讲出了我博客地址,那么如果谁愿意跟我交换友情连接的可以跟我说,咱们可以多交流交流~毕竟Flash未来良好的发展趋势,还是得靠我们一步步共同去挖掘。
图片名称:会场现场 ![]() |
因为我公司是全封闭式开发,所有1年多来已经习惯不开IM软件(当然除了QQ,也包括MSN等主流通讯软件),所以今天在会场上有人问及我QQ还有MSN什么的,很不好意思我是真的很久没上过了,不过大家想找我可以博客留言,如果是有问题在博客留言,我承诺一定会在最短时间解答你的问题,当然我也不是万能的,涉及到框架问题我帮不了你,我不是很喜欢用框架,虽然我会去研究ASWing,PV3D等主流框架的底层结构,但从来没用过,正如今天会场上有位帅哥讲的一样,简单才是最好的。
另外大家也可以发电子邮件找我:sunkill@163.com(不是很频繁看邮箱,如果回信速度慢了,请多见谅)
当然硬说没QQ,大家也不会相信,我QQ是36806312,不过真的很久没上了,不过最近可能会上一下,当然是因为这次会场的缘故拉










- 查看svn更新内容以及最新状态(实时更新)
- 查看框架API文档(09.6.15更新)
- 查看框架代码(09.4.20更新)
FireAS开源框架QQ交流群:20496960目前加入的人不多,如果你选择加入了该群,表明你支持这套框架,若不支持请不要加入!