연관 배열

Flash Player 9 이상, Adobe AIR 1.0 이상

해시 또는 이라고도 하는 연관 배열은 숫자 인덱스 대신 를 사용하여 저장된 값을 구성합니다. 연관 배열의 각 키는 저장된 값에 액세스하기 위해 사용되는 고유한 문자열입니다. 연관 배열은 Object 클래스의 인스턴스이며 각 키는 속성 이름에 해당합니다. 연관 배열은 정렬되지 않은 키/값 쌍 모음입니다. 코드에서 연관 배열의 키가 특정한 순서로 되어 있으면 안 됩니다.

ActionScript 3.0에는 사전이라는 고급 연관 배열 유형이 포함되었습니다. 사전은 flash.utils 패키지에 있는 Dictionary 클래스의 인스턴스로, 모든 데이터 유형의 키를 사용합니다. 즉, 사전 키에는 String 유형이 아닌 값도 사용할 수 있습니다.

문자열 키가 있는 연관 배열

ActionScript 3.0에서는 두 가지 방법으로 연관 배열을 만들 수 있습니다. 첫 번째 방법은 Object 인스턴스를 사용하는 것입니다. Object 인스턴스를 사용하면 객체 리터럴로 배열을 초기화할 수 있습니다. 일반 객체라고도 하는 Object 클래스의 인스턴스는 연관 배열과 기능면에서 동일합니다. 일반 객체의 각 속성 이름은 저장된 값에 대한 액세스를 제공하는 키 역할을 합니다.

다음 예제는 monitorInfo라는 연관 배열을 만들고, 객체 리터럴을 사용하여 두 개의 키/값 쌍으로 배열을 초기화합니다.

var monitorInfo:Object = {type:"Flat Panel", resolution:"1600 x 1200"}; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

선언 시 배열을 초기화할 필요가 없을 경우에는 다음과 같이 Object 생성자를 사용하여 배열을 만들 수 있습니다.

var monitorInfo:Object = new Object();

객체 리터럴이나 Object 클래스 생성자를 사용하여 배열을 만든 후에는 배열 액세스([]) 연산자나 도트 연산자(.)를 사용하여 배열에 새 값을 추가할 수 있습니다. 다음 예제에서는 두 개의 새로운 값을 monitorArray에 추가합니다.

monitorInfo["aspect ratio"] = "16:10"; // bad form, do not use spaces 
monitorInfo.colors = "16.7 million"; 
trace(monitorInfo["aspect ratio"], monitorInfo.colors); 
// output: 16:10 16.7 million

aspect ratio 키에는 공백 문자가 포함됩니다. 이는 배열 액세스([]) 연산자를 사용하는 경우에만 가능하고 도트 연산자를 사용하는 경우에 공백 문자가 포함되면 오류가 발생합니다. 그러나 키 이름에 공백을 사용하는 것은 권장되지 않습니다.

연관 배열을 만드는 두 번째 방법은 Array 생성자(또는 동적 클래스의 생성자)를 사용한 다음 배열 액세스([]) 연산자나 도트 연산자(.)를 사용하여 배열에 키/값 쌍을 추가하는 것입니다. 연관 배열을 배열 유형으로 선언할 경우에는 객체 리터럴을 사용하여 배열을 초기화할 수 없습니다. 다음 예제에서는 Array 생성자를 사용하여 monitorInfo라는 연관 배열을 만들고 type이라는 키와 resolution이라는 키를 각각의 값과 함께 추가합니다.

var monitorInfo:Array = new Array(); 
monitorInfo["type"] = "Flat Panel"; 
monitorInfo["resolution"] = "1600 x 1200"; 
trace(monitorInfo["type"], monitorInfo["resolution"]);  
// output: Flat Panel 1600 x 1200

Array 생성자를 사용하여 연관 배열을 만들어도 별다른 이점은 없습니다. Array 생성자나 Array 데이터 유형을 사용하는 경우에도 연관 배열에 Array.length 속성이나 Array 클래스의 메서드를 모두 사용할 수 없습니다. Array 생성자는 인덱스 배열을 만드는 데 사용하는 것이 가장 좋습니다.

객체 키가 있는 연관 배열(Dictionary)

Dictionary 클래스를 사용하여 문자열이 아닌 객체를 키로 사용하는 연관 배열을 생성할 수 있습니다. 이러한 배열을 사전, 해시 또는 맵이라고도 합니다. 예를 들어 특정 컨테이너와의 연관성을 기준으로 Sprite 객체의 위치를 결정하는 응용 프로그램을 살펴봅니다. 이 경우 Dictionary 객체를 사용하여 컨테이너에 각 Sprite 객체를 매핑할 수 있습니다.

다음 코드는 Dictionary 객체의 키 역할을 수행할 Sprite 클래스의 세 가지 인스턴스를 만듭니다. 각 키에는 GroupA 또는 GroupB의 값이 할당됩니다. 값은 모든 데이터 유형이 될 수 있지만 이 예제에서는 GroupAGroupB가 모두 Object 클래스의 인스턴스입니다. 그런 후 다음 코드와 같이 배열 액세스([]) 연산자를 사용하여 각 키와 연관된 값에 액세스할 수 있습니다.

import flash.display.Sprite; 
import flash.utils.Dictionary; 
 
var groupMap:Dictionary = new Dictionary(); 
 
// objects to use as keys 
var spr1:Sprite = new Sprite(); 
var spr2:Sprite = new Sprite(); 
var spr3:Sprite = new Sprite(); 
 
// objects to use as values 
var groupA:Object = new Object(); 
var groupB:Object = new Object(); 
 
// Create new key-value pairs in dictionary. 
groupMap[spr1] = groupA; 
groupMap[spr2] = groupB; 
groupMap[spr3] = groupB; 
 
if (groupMap[spr1] == groupA) 
{ 
    trace("spr1 is in groupA");  
} 
if (groupMap[spr2] == groupB) 
{ 
    trace("spr2 is in groupB");  
} 
if (groupMap[spr3] == groupB) 
{ 
    trace("spr3 is in groupB");  
}

객체 키로 반복

for..in 루프나 for each..in 루프를 사용하여 Dictionary 객체의 내용을 반복할 수 있습니다. for..in 루프를 사용하면 키를 기준으로 반복할 수 있으며, for each..in 루프를 사용하면 각 키와 연관된 값을 기준으로 반복할 수 있습니다.

Dictionary 객체의 객체 키에 직접 액세스하려면 for..in 루프를 사용합니다. 배열 액세스([]) 연산자를 사용하여 Dictionary 객체의 값에 액세스할 수도 있습니다. 다음 코드에서는 groupMap 사전의 이전 예제를 사용하여 for..in 루프를 통해 Dictionary 객체를 반복하는 방법을 보여 줍니다.

for (var key:Object in groupMap) 
{ 
    trace(key, groupMap[key]); 
} 
/* output: 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
[object Sprite] [object Object] 
*/

Dictionary 객체의 값에 직접 액세스하려면 for each..in 루프를 사용합니다. 다음 코드에서는 groupMap 사전을 사용하여 for each..in 루프를 통해 Dictionary 객체를 반복하는 방법을 보여 줍니다.

for each (var item:Object in groupMap) 
{ 
    trace(item); 
} 
/* output: 
[object Object] 
[object Object] 
[object Object] 
*/

객체 키 및 메모리 관리

Adobe® Flash® Player 및 Adobe® AIR™에서는 가비지 컬렉션 시스템을 사용하여 더 이상 사용되지 않는 메모리를 복구합니다. 객체에 객체를 가리키는 참조가 없을 경우 객체는 가비지 컬렉션의 대상이 되며 다음 번 가비지 컬렉션 시스템 실행 시 메모리가 복구됩니다. 예를 들어 다음 코드는 새 객체를 만들어 변수 myObject에 객체에 대한 참조를 할당합니다.

var myObject:Object = new Object();

객체에 대한 참조가 남아 있는 한, 가비지 컬렉션 시스템에서는 객체가 사용하고 있는 메모리를 복구하지 않습니다. 다른 객체를 가리키거나 null 값으로 설정되는 등 myObject 값이 변경되면, 원래 객체에 의해 사용되던 메모리는 가비지 컬렉션의 대상이 됩니다. 그러나 이 원래 객체에 대한 다른 참조가 없는 경우에만 해당됩니다.

Dictionary 객체에서 myObject를 키로 사용하는 경우 원래 객체에 대한 다른 참조가 만들어집니다. 예를 들어 다음 코드에서는 객체에 대한 두 개의 참조 즉, myObject 변수 및 myMap 객체의 키를 만듭니다.

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(); 
myMap[myObject] = "foo";

myObject로 참조되는 객체를 가비지 컬렉션 대상으로 만들려면 객체에 대한 참조를 모두 제거해야 합니다. 이 경우, 다음 코드와 같이 myObject 값을 변경하고 myMap에서 myObject 키를 삭제해야 합니다.

myObject = null; 
delete myMap[myObject];

또는 Dictionary 생성자의 useWeakReference 매개 변수를 사용하여 사전 키를 모두 약한 참조로 만들 수 있습니다. 가비지 컬렉션 시스템에서는 약한 참조를 무시하므로 약한 참조만 있는 객체는 가비지 컬렉션의 대상이 됩니다. 예를 들어 다음 코드에서는 객체를 가비지 컬렉션 대상으로 만들기 위해 myMap에서 myObject 키를 삭제할 필요가 없습니다.

import flash.utils.Dictionary; 
 
var myObject:Object = new Object(); 
var myMap:Dictionary = new Dictionary(true); 
myMap[myObject] = "foo"; 
myObject = null; // Make object eligible for garbage collection.