Tôi có một hàm có chức năng khác làm tham số. Một cái gì đó như thế này:AS3 truyền hàm như một tham số tạo ra rò rỉ bộ nhớ
public function onHits(target : Shape, callback : Function) : void
Tôi sử dụng nó bằng cách chuyển một hàm thành viên như một tham số cần được gọi bất cứ khi nào mục tiêu được truyền đạt đến thứ gì đó. Hàm này được gọi nhiều lần một khung. Vì vậy, nó được sử dụng bằng cách thực hiện:
//code...
CollisionManager.onHits(myShape, onHitCB);
//code...
Các chức năng trên hit:
public function onHitCB(hitObject : *) : void
{
//removed all code to test this problem
}
Khi tôi làm điều này, tôi có một rò rỉ bộ nhớ. Tôi đã phân lập vấn đề với phương thức onHits đó và đã nhận xét mọi thứ khác. onHits là một phương thức rỗng không có mã bên trong nó, onHitCB cũng rỗng. Nếu tôi nhận xét các cuộc gọi đến onHits, không có rò rỉ bộ nhớ và nếu tôi vượt qua null thay vì onHitCB không có rò rỉ bộ nhớ.
Vì vậy, rõ ràng khi tôi chuyển onHitCB thành thông số. Vì vậy, tôi nghĩ rằng nó có thể là do Flash phân bổ một số bộ nhớ để tạo ra các con trỏ hàm và không phát hành nó nhưng tôi gọi System.gc() mỗi khung trong chế độ gỡ lỗi và rò rỉ vẫn còn đó. Điều này có nghĩa là đây là lỗi trong SDK hoặc tôi không làm điều gì đúng.
Tôi đã tìm thấy một workaround lạ bằng cách giữ một biến trỏ đến các chức năng mà tôi gán trong constructor của đối tượng của tôi:
private var func : Function;
public function MyObject()
{
func = onHitCB;
}
và điều này sẽ xóa bộ nhớ bị rò rỉ ngay cả khi tôi vẫn vượt qua onHitCB làm tham số. Vì vậy, điều đó có nghĩa rằng nó không phải là "getter" chức năng để có được onHitCB nhưng cái gì khác gây ra rò rỉ bộ nhớ?
Tôi rất bối rối. Làm thế nào điều này có thể gây ra rò rỉ bộ nhớ:
public function MyObject()
{
}
public function update() : void
{
CollisionManager.onHits(myShape, onHitCB);//empty function
}
public function onHitCB(hitObject : *) : void
{
//removed all code to test this problem
}
nhưng không phải điều này? :
private var func : Function;
public function MyObject()
{
func = onHitCB;
}
public function update() : void
{
CollisionManager.onHits(myShape, onHitCB);//empty function
}
public function onHitCB(hitObject : *) : void
{
//removed all code to test this problem
}
và có cách nào để không phải thực hiện giải pháp này không?
Tại sao không đặt onHitCB thành viên của lớp thành CollisionManager? Âm thanh như chức năng của bạn là mất phạm vi. Trên dòng cuối cùng của onHits, hãy thử gọi lại = null; –
Đã cố gắng thiết lập gọi lại thành vô giá trị ở cuối onHits nhưng vẫn có lỗ rò. Cho đến nay, việc giữ một tham chiếu cục bộ đến hàm là giải pháp duy nhất tôi có thể tìm thấy. – Godfather