참조에 의한 할당 (Reference Assignment) 문제 (Flutter)

2024. 4. 1. 15:31프로그래밍/Flutter

참조에 의한 할당 (Reference Assignment) 문제 (Flutter)
Deep Copy

참조에 의한 할당 (Reference Assignment)

 

List A의 값을 할당받는 List B의 값을 변경하면 A와 B 두 리스트 모두의 값이 변하는 문제

var listA = [{'name': '민수'}];
var listB = listA; 
listB[0]['name'] = '철수';
print(listA[0]['name']); // '철수' 출력

 

왜 이런 문제가 발생하는거야?

List B가 ListA를 참조하고 있다면 메모리의 같은 주소를 바라보고 있기 때문에 한 리스트에서의 변경이 다른 리스트에도 영향을 미친다,

이것은 '얕은 복사'(shallow copy)라고도 불리며 객체나 리스트를 다룰 때 흔히 발생하는 문제이므로 조심해야한다

 

이 문제를 해결하기 위해서는 각 리스트가 독립적인 리스트가 되야 하고 이들을 초기화 할 때 모든 요소를 새로운 메모리 주소로 복사하는 '깊은 복사'(deep copy)를 사용해야 한다

Dart에서는 Map.from 이나 리스트의 ...(스프레드 연산자) 를 사용하여 객체나 리스트의 복사본을 만들 수 있다

이렇게 하면 한 리스트에서의 변경이 다른 리스트에 영향을 미치지 않는다

var listA = [{'name': ''민수}];
var listB = List.from(listA.map((item) => Map.from(item))); // deep copy
listB[0]['name'] = '철수';
print(listA[0]['name']); // '민수' 출력됨

 

나의 경우는

RxList<Map<String,dynamic>> 형태의 리스트를 다루기 때문에 deep copy 방식이 다르다

import 'package:get/get.dart';

void deepCopyRxList() {
  RxList<Map<String, dynamic>> listA = <Map<String, dynamic>>[].obs;
  RxList<Map<String, dynamic>> listB = <Map<String, dynamic>>[].obs;

  // listA에 샘플 데이터 추가 (예시)
  listA.add({'id': 1, 'name': 'Item 1'});
  listA.add({'id': 2, 'name': 'Item 2'});

  // listB에 listA의 내용을 깊은 복사
  listB.value = listA.map((map) => Map<String, dynamic>.from(map)).toList().obs;

  // listA를 변경해도 listB에 영향을 주지 않음
  listA[0]['name'] = 'Changed Item';

  // listA와 listB의 내용을 출력
  print('listA: $listA'); // listA: [{id: 1, name: Changed Item}, {id: 2, name: Item 2}]
  print('listB: $listB'); // listB: [{id: 1, name: Item 1}, {id: 2, name: Item 2}]
}

void main() {
  deepCopyRxList();
}

 

일반 List와 RxList의 deep copy 방식 비교

// 일반 List
var listB = List.from(
	listA.map((item) => 
		Map.from(item)
	)
); // 일반 List 깊은 복사

// RxList
var listB = listA.map((map) => 
	Map<String, dynamic>.from(map)
).toList().obs;

 

 

#참조, #ReferenceAssignment, #DeepCopy, #ShallowCopy, #DartDeepCopyVsShallowCopy, #FlutterShallowCopy, #FlutterDeepCopy