2012-04-05 25 views
5

Hiện tại, tôi đang thử nghiệm với một bản vẽ GUI rất đơn giản ... "động cơ" (tôi đoán bạn có thể gọi nó là). Ý chính của nó:xây dựng công cụ GUI nhỏ: hiển thị so với addChild/removeChild

  1. có một FrontController bị truy cập bởi các yêu cầu của người dùng; mỗi yêu cầu có một uid
  2. mỗi uid (đọc "trang") đã ra tuyên bố của các thành phần ("module") có mặt trên đó
  3. thành phần là Sprite lớp con, và trong bản chất, là duy nhất

Đương nhiên, tôi cần cách ẩn/hiển thị các sprites này. Hiện nay, tôi có nó khá giống như Flex có nó theo mặc định - trong cách "nếu chúng ta đang ở một nơi mà comp có thể nhìn thấy, tạo nó, cache nó và tái sử dụng nó mỗi khi nó có thể nhìn thấy một lần nữa".

Câu hỏi đặt ra là - cách thức phù hợp và hiệu quả hơn để ẩn và hiển thị - qua số addChild/removeChild hoặc toggling visible.

Cách tôi nhìn thấy nó là:

  • visible là nhanh chóng và dơ bẩn (các bài kiểm tra đầu tiên)
  • visible không tạo ra một chuỗi các sự kiện bọt như Event.ADDED hoặc Event.REMOVED
  • thành phần vô hình don không nhận được sự kiện chuột

Vì vậy, removeChild sẽ là điều tôi muốn gọi khi tôi ' chắc chắn, thành phần đó sẽ không còn cần thiết trên màn hình (hoặc bộ nhớ cache quá lớn), ví dụ:

Những người xếp chồng/người có suy nghĩ AS3 nghĩ gì?

Cập nhật: Đây là good read (quên về google).

tôi sẽ gắn bó với visible; nó có vẻ phù hợp với nhiệm vụ của tôi tốt hơn; hướng dẫn sử dụng "TÍNH CHẤT TỐI ƯU HÓA CHO TUYỆT VỜI FLASH" của Adobe trên trang. 69 đã giúp tôi tự tin hơn.

đây là một đoạn mã tôi đặt lên để kiểm tra mọi thứ cho những người quan tâm:

package 
{ 
import flash.display.Sprite; 
import flash.display.Stage; 
import flash.events.Event; 
import flash.events.KeyboardEvent; 
import flash.ui.Keyboard; 
import flash.utils.getTimer; 

/** 
* Simple benchmark to test alternatives for hiding and showing 
* DisplayObject. 
* 
* Use: 
* <code> 
* new DisplayBM(stage); 
* </code> 
* 
* Hit: 
* - "1" to addChild (note that hitting it 2 times is expensive; i think 
* this is because the player has to check whether or not the comp is 
* used elsewhere) 
* - "q" to removeChild (2 times in a row will throw an exception) 
* - "2" to set visible to true 
* - "w" to set visible to false 
* 
* @author Vasi Grigorash 
*/  
public class DisplayBM{ 
    public function DisplayBM(stage:Stage){ 
     super(); 

     var insts:uint = 5000; 
     var v:Vector.<Sprite> = new Vector.<Sprite>(insts); 
     var i:Number = v.length, s:Sprite 
     while (i--){ 
      s = new Sprite; 
      s.graphics.beginFill(Math.random() * 0xFFFFFF); 
      s.graphics.drawRect(
       Math.random() * stage.stageWidth, 
       Math.random() * stage.stageHeight, 
       10, 
       10 
      ); 
      s.graphics.endFill(); 
      v[i] = s; 
     } 

     var store:Object = {}; 
     store[Event.ADDED] = null; 
     store[Event.REMOVED] = null; 
     var count:Function = function(e:Event):void{ 
      store[e.type]++; 
     } 
     var keydown:Function = function (e:KeyboardEvent):void{ 
      var key:String 
      //clear event counts from last run 
      for (key in store){ 
       store[key] = 0; 
      } 

      stage.addEventListener(Event.ADDED, count); 
      stage.addEventListener(Event.REMOVED, count); 

      var s0:uint = getTimer(), op:String; 
      var i:Number = v.length; 
      if (e.keyCode === Keyboard.NUMBER_1){ 
       op = 'addChild'; 
       while (i--){ 
        stage.addChild(v[i]); 
       } 
      } 
      if (e.keyCode === Keyboard.Q){ 
       op = 'removeChild'; 
       while (i--){ 
        stage.removeChild(v[i]); 
       } 
      } 
      if (e.keyCode === Keyboard.NUMBER_2){ 
       op = 'visibile'; 
       while (i--){ 
        v[i].visible = true; 
       } 
      } 
      if (e.keyCode === Keyboard.W){ 
       op = 'invisibile'; 
       while (i--){ 
        v[i].visible = false; 
       } 
      } 
      if (op){ 
       //format events 
       var events:Array = []; 
       for (key in store){ 
        events.push(key + ' : ' + store[key]) 
       } 

       trace(op + ' took ' + (getTimer() - s0) + ' ' + events.join(',')); 
      } 

      stage.removeEventListener(Event.ADDED, count); 
      stage.removeEventListener(Event.REMOVED, count); 
     } 

     //autodispatch 
     stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown); 
    } 
} 
} 
+1

Nếu những gì tôi cần để ẩn/hiển thị sử dụng rất nhiều nguồn lực, thường tôi sẽ removeChild/addChild qua Cài đặt hiển thị của nó. Nếu thứ gì đó nhỏ hoặc ít phức tạp như một trường đồ họa hoặc văn bản, tôi sẽ đặt mức độ hiển thị hoặc alpha của nó. Tất cả phụ thuộc vào những gì nó là bạn cần phải ẩn/hiển thị – Ronnie

+0

@Ronnie removeChild chỉ loại bỏ các mục từ danh sách hiển thị - không có gì nhiều hơn nữa. –

+0

xin lỗi, tôi thiết lập nó để null quá và tái tạo khi tôi cần nó – Ronnie

Trả lời

2

Visible có ý nghĩa hơn đối với tôi (vì loại bỏ một đứa trẻ chỉ ra một dứt khoát) và là những gì tôi có xu hướng sử dụng trong các dự án của riêng tôi khi hiển thị/ẩn.

Tôi cũng giả định rằng addChild kém hiệu quả hơn một chút nhưng tôi chưa thực hiện bất kỳ thử nghiệm nào.

CHỈNH SỬA: Tôi vừa xem qua bài viết này http://help.adobe.com/en_US/as3/mobile/WS5d37564e2b3bb78e5247b9e212ea639b4d7-8000.html chỉ định rằng khi sử dụng chế độ hiển thị GPU, thiết lập hiển thị = false có thể có tác động hiệu suất vì có chi phí vẽ đối tượng trùng nhau (mặc dù chúng không hiển thị).Thay vào đó, hãy xóa hoàn toàn trẻ em được khuyên:

Tránh rút quá bất cứ khi nào có thể. Quá trình thu hồi đang phân lớp nhiều phần tử đồ họa để chúng che khuất lẫn nhau. Sử dụng phần mềm renderer , mỗi pixel chỉ được vẽ một lần. Do đó, đối với phần mềm hiển thị , ứng dụng sẽ không bị phạt hiệu suất bất kể số lượng phần tử đồ họa bao phủ nhau tại vị trí pixel đó. Ngược lại, trình kết xuất phần cứng vẽ từng pixel cho mỗi phần tử cho dù các phần tử khác che khuất vùng đó hay không. Nếu hai hình chữ nhật chồng lên nhau, trình kết xuất phần cứng vẽ vùng chồng chéo hai lần trong khi trình kết xuất phần mềm vẽ vùng chỉ một lần.

Do đó, trên màn hình, sử dụng trình kết xuất phần mềm, bạn thường không nhận thấy tác động hiệu suất của việc rút tiền. Tuy nhiên, nhiều hình dạng chồng chéo có thể ảnh hưởng xấu đến hiệu suất trên các thiết bị bằng cách sử dụng kết xuất GPU. Cách tốt nhất là xóa đối tượng khỏi danh sách hiển thị thay vì ẩn chúng.

+0

Đây là những gì tôi có xu hướng suy nghĩ là tốt. Nó dễ dàng hơn cho người chơi để làm việc trong điều khoản của "vẽ/không vẽ" hơn "thêm vào danh sách hiển thị, cập nhật danh sách hiển thị, sinh sản và bong bóng sự kiện, vẽ" và cách trở lại. Các thử nghiệm đơn giản đầu tiên (không phải kiểm tra đơn vị) cho thấy giao diện người dùng phản ứng nhanh hơn khi thao tác nó thông qua 'hiển thị'; tôi sẽ phải nghiên cứu sâu hơn một chút. –

1

Xóa trẻ tốt hơn để giảm các trường hợp, sự kiện và giải phóng bộ nhớ khỏi phim flash của bạn, Bạn có thể tìm thấy sau thời gian các sprites có thể ảnh hưởng lẫn nhau.Từ cách chúng được vẽ hoặc có listneres. vào chơi khi phương pháp này được thực hiện mà có thể cực kỳ vặn vẹo xung quanh với ứng dụng của bạn

Có thể nhìn thấy vẫn còn ma trong bộ nhớ, nó hiện không được rút ra. Bạn cũng có thể lưu lại và sau đó loại bỏ nó, sau đó tải lại khi cần thiết là một lý tưởng trên tất cả các giải pháp. sử dụng mảng để lưu trữ dữ liệu là một giải pháp khác tùy thuộc vào cách ứng dụng của bạn được triển khai, khó nói như chúng tôi không biết, lol

Thêm hiệu suất con tôi sẽ nói là ít căng thẳng hơn vì mục duy nhất của nó thêm và bội số được ẩn. Ngoài ra trong các trẻ em ẩn "s" có tài sản được lưu trữ bộ nhớ im cùng với người nghe.

+0

Như đã chú ý bởi @Pixel Elephant - 'removeChild' sẽ không làm giảm trường hợp của bạn, nó sẽ xóa các tham chiếu. Nếu nó xảy ra thì đó là những ref duy nhất trỏ đến đối tượng - chúng sẽ được gc'ed và, do đó, giải phóng bộ nhớ. Tôi chưa thử nghiệm kỹ lưỡng, nhưng từ quan điểm của người dùng - 'visible' hoạt động nhanh hơn' addChild' và 'removeChild'. Không có sự kiện nào được sinh ra. Người nghe có thể được bỏ đặt cùng với 'mức độ hiển thị' (giống như đã được khôi phục). –

+0

để bạn nói cho tôi biết nếu tôi tạo một vòng lặp thêm 500 đối tượng vào sân khấu với người nghe, khi họ vô hình thì người nghe vẫn còn tồn tại? từ bộ nhớ – joshua

+0

không chính xác; 'removeChild' hoặc' visible = false' trên 500 đối tượng - người nghe sẽ vẫn ở đó. Sự khác biệt duy nhất trong 'visible = false' và' removeChilded' comp là lần đầu tiên nhận được các sự kiện sân khấu; thứ hai - không. Những gì tôi có nghĩa là bởi "không có sự kiện được sinh ra" - là 'vô hình = false' không đẻ trứng bất cứ điều gì. 'addChild' và' removeChild' - làm các sự kiện sinh sản. –

Các vấn đề liên quan