2011-10-08 47 views
10

Ứng dụng của tôi sử dụng một từ điểnTại sao xóa (DictionaryInstance [key]); Thất bại?

protected _categoryToValueDict:Dictionary = new Dictionary(); 

để ánh xạ một cái gì đó để cái gì khác.

Bây giờ, tại một thời điểm nhất định trong ứng dụng, tôi cần phải xóa một khóa nhất định khỏi Dictionary.

tôi thực hiện phương pháp đơn giản này:

public function setCategoryNoValue(cat:TAModelCategory):void { 

     // delete(_categoryToValueDict[ cat ]); 

     var old:Dictionary = _categoryToValueDict; 

     _categoryToValueDict = new Dictionary(); 

     for (var key:* in old) { 

      if (key != cat) { 
       _categoryToValueDict[ key ] = old[ key ]; 
      } 
     } 

    } 

Nếu tôi chỉ sử dụng [mô tả của các nhà điều hành delete]

delete(_categoryToValueDict[ cat ]); 

ứng dụng riêng của mình không ném sai sót trong chế độ bình thường. Nhưng ngay sau khi tôi serialize cấu trúc dữ liệu bên ngoài của nó sang nguồn bên ngoài [hiện tại SharedObject], ứng dụng không thể hủy nối tiếp sau này.

Nếu tôi sử dụng mã hóa trên tay loại bỏ lặp đi lặp lại hoạt động, hoạt động de-serialize công trình như mong đợi và mô hình xuất hiện trong ứng dụng.

Phương án thay thế phải giống hệt nhau. Phải không?

Vì vậy, câu hỏi của tôi: Sự khác biệt giữa hai lựa chọn thay thế là gì?

PS: Câu hỏi này có thể có liên quan đến my previous one.

CẬP NHẬT-1

Adobe giải thích trên this page:


Để thực hiện các đối tượng được tham chiếu bởi myObject đủ điều kiện để thu gom rác thải, bạn phải loại bỏ tất cả các tham chiếu tới nó. Trong trường hợp này, bạn phải thay đổi giá trị của myObject và xóa khóa myObject từ myMap, như trong đoạn mã sau:

myObject = null; 
delete myMap[myObject]; 

là cho rằng đây là một lỗi đánh máy. Không nên đọc như sau:

delete myMap[myObject]; 
myObject = null; 

Tại sao chuyển con trỏ rỗng vào myMap làm khóa?

+0

+1 cho câu hỏi được giải thích rõ ràng và thực hiện một số nghiên cứu trước khi đăng. – JeffryHouser

+0

Xem lại mã của bạn; nguồn của phương thức "xóa" ở đâu? – JeffryHouser

+1

@ www.Flextras.com xóa là toán tử chứ không phải phương thức. Vì vậy, tôi đã không cung cấp một phương pháp. – SteAp

Trả lời

8

Được rồi, tôi chỉ dành hai giờ đồng hồ để xem xét điều này, đó là cách nhiều hơn tôi dự định chi tiêu để xem xét điều này. Nhưng tôi bị hấp dẫn.

Tôi nghĩ rằng bạn có thể đã phát hiện ra một lỗi hợp pháp trong mã hóa AMF của ActionScript (hoặc trong cách lớp Dictionary được mã hóa thông qua AMF). Lỗi này ảnh hưởng đến bất cứ thứ gì sử dụng AMF, vì vậy lỗi chính xác có thể tái tạo với ByteArray, vì vậy tôi sẽ sử dụng nó cho mục đích trình diễn.

Xét đoạn mã sau:

 var d:Dictionary = new Dictionary(false); 
     d["goodbye"] = "world"; 
     d["hello"] = "world"; 
     delete d["hello"] 

     var ba:ByteArray = new ByteArray(); 
     ba.writeObject(d); 

     var len:uint = ba.position; 
     ba.position = 0; 
     for(var i:uint=0;i<len;i++) { 
      trace(ba.readUnsignedByte().toString(16)); 
     } 

Kết quả sẽ là:

11 05 00 06 0f 67 6f 6f 64 62 79 65 06 0b 77 6f 72 6c 64

Bây giờ những gì nếu chúng ta không bao giờ đưa "hello" trong như một chìa khóa:

 var d:Dictionary = new Dictionary(false); 
     d["goodbye"] = "world"; 

     var ba:ByteArray = new ByteArray(); 
     ba.writeObject(d); 

     var len:uint = ba.position; 
     ba.position = 0; 
     for(var i:uint=0;i<len;i++) { 
      trace(ba.readUnsignedByte().toString(16)); 
     } 

Kết quả sau đó là:

11 03 00 06 0f 67 6f 6f 64 62 79 65 06 0b 77 6f 72 6c 64

Lưu ý rằng độ dài chính xác giống nhau, tuy nhiên chúng khác nhau ở byte thứ hai.

Bây giờ cho phép nhìn vào serialization vì nếu tôi không xóa "hello":

11 05 01 06 0b 68 65 6c 6c 6f 06 0b 77 6f 72 6c 64 06 0f 67 6f 6f 64 62 79 65 06 02

ý rằng 05 trong byte thứ hai cũng giống như khi chúng ta xóa nó. Tôi nghĩ rằng đây là việc xác định số lượng các mục trong Từ điển. Tôi nói "Tôi nghĩ" vì tôi đào sâu tài liệu về AMF0/3 trong một thời gian dài để tìm ra chính xác những gì đang xảy ra ở đây, bởi vì nó không có vẻ như đây là serialization cho một từ điển, nhưng nó khá nhất quán nhưng tôi không hiểu. Vì vậy, tôi nghĩ rằng đó là lý do tại sao bạn đang đánh một ngoại lệ (cụ thể là lỗi "Kết thúc tệp"), bởi vì nó vẫn cho rằng nên có một mục khác trong từ điển mà nó nên được loại bỏ.

Phương pháp thay thế của bạn hoạt động vì bạn đang xây dựng một từ điển mới và điền vào nó ... "bộ đếm nội bộ" của nó chỉ tăng lên, vì vậy nó hoạt động như một sự quyến rũ.

Một điều cần lưu ý, rằng nếu bạn đặt d["Hello"] = undefined, nó không ném ngoại lệ, nhưng mục không không bị xóa khỏi từ điển. Khóa được tuần tự hóa với giá trị là undefined trong luồng AMF. Vì vậy, luồng byte kết quả dài hơn nếu nó không bao giờ ở đó.

Sử dụng Object dường như không thể hiện hành vi tương tự này. Không chỉ không tạo ra lỗi, mã bytecode được tạo ra phù hợp hơn với tài liệu AMF0/3 mà tôi có thể tìm thấy từ Adobe. Và "khóa" kết quả theo nghĩa đen đã bị loại bỏ khỏi việc tuần tự hóa, giống như thực tế nó không bao giờ ở đó. Vì vậy, tôi không chắc chắn trường hợp đặc biệt mà họ đang sử dụng cho Dictionary (rõ ràng là không có giấy tờ AMF3 datatype 0x11), nhưng nó không chơi đúng với xóa các mục ra khỏi nó.

Dường như đó là lỗi hợp pháp đối với tôi.

chỉnh sửa

Vì vậy, tôi đào xung quanh một chút và thấy người khác nói về AMF serilization of a Dictionary.

0x11 : Dictionary Data Type 
0x05 : Bit code: XXXX XXXY 
    : If y == 0 then X is a reference to a previously encoded object in the stream 
    : If y == 1 then X is the number of key/val pairs in the dictionary. 

Vì vậy, nếu trường hợp này 5&1 == 15>>1 == 2, vì vậy nó mong đợi cặp hai chìa khóa/val trong phiên bản serialized "xấu".

+0

Công việc tuyệt vời! Cảm ơn nhiều! Tôi sẽ gửi báo cáo lỗi. – SteAp

+0

@SteAp: bạn có bao giờ đi xung quanh để gửi báo cáo lỗi không? Tôi nhấn cùng một vấn đề ngày hôm nay và tôi đã cố gắng tìm kiếm một báo cáo lỗi liên quan trong trình theo dõi lỗi nhưng không thể tìm thấy bất kỳ lỗi nào. –

+0

Hm, không, tôi đã gửi một lỗi, nhưng Adobe thậm chí không trả lời. Không chắc chắn, nếu vấn đề vẫn tồn tại trong bản phát hành FB/AIR hiện tại. Cần kiểm tra nguồn của tôi, cách tôi giải quyết vấn đề. Sẽ quay lại sau .. – SteAp

0

cú pháp đúng cho delete operator là như thế này:

delete _categoryToValueDict[ cat ]; 

Mặc dù sử dụng ngoặc dường như biên dịch tốt, nó không phải là cách đúng.

+0

sau khi một số thử nghiệm, có vẻ như là sử dụng dấu ngoặc đơn làm việc giống như không sử dụng chúng, vì vậy điều này có thể không làm việc cho bạn. – grapefrukt

+1

Trên thực tế, toán tử xóa không yêu cầu dấu ngoặc đơn. Vì tham số xóa là một biểu thức và xung quanh một biểu thức với dấu ngoặc đơn của nó là một biểu thức hợp lệ nữa, nó hoàn toàn hợp pháp để viết delete (...). – SteAp

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