Skip to main content

02. [KOSTA] 플러터 심화 교육

Dart 학습


객체 생성

객체 변수에는 메모리 주소를 반환한다.

그래서

객체1 == 객체1은 참조비교라고 주소를 비교하는 것이다.

'a' == 'a' // true
[1] == [1] //false

가변 객체와 불변 객체

불변 객체'a'같은 값이다. 값이 변경되지 않는다.

가변 객체는 같은 내용인 것처럼 보여도 수정이 가능해서 항상 새로운 메모리 주소 할당

예시로 list, set, map, class 등이 있다.

가변 객체는 항상 다른 메모리 주소 할당

불변 객체 예시는 string, int, double, bool, const로 선언된 객체 등이 있다.

Flutter에서는 값이 변경되지 않는 위젯은 const를 붙이는 것이 메모리 절약할 수 있다.

값 비교

직접 코드로 짜려면 비교하는 operator를 오버라이딩해서 사용해야한다.

주의할 점은 final이나 const로 불변객체로 만들지 않으면 hashcode도 바꿔줘야한다.

class A {
final int value;

// final로 선언된 인스턴스가 있어야 const로 생성자 만들 수 있음.
const A(this.value);

// ==라는 operator를 오버라이딩한 것임.


bool operator ==(Object other) {
// identical은 참조 비교
// 그러나 값 비교를 위해서 ||를 추가함
return identical(this, other) ||
// this.runtimeType == other.runtimeType이다.
// this.value와 other.value이다.
// 둘이 메모리 주소는 달라도 값이 다르면 true를 반환할 것이다.
other is A && runtimeType == other.runtimeType && value == other.value;
}

// 불변객체로 선언하면 이거 안해도 된다.

int get hashCode => value.hashCode;

// toString함수를 오버라이딩 해서 문자열로 출력되도록 한 것

String toString() {
return "A($value)";
}
}

void main() {
print(A(1) == A(1));
print(A(1));
}

equatable 라이브러리를 사용하면 쉽게 값 비교를 할 수 있다.

import 'package:equatable/equatable.dart';

class A extends Equatable {
final int value;

const A(this.value);


List<Object?> get props => [value];
}

void main() {
print(A(1) == A(1));
print(A(1));
}

복사


얕은 복사 : 메모리 주소만 전달하는 것

깊은 복사 :

Map

Map 자료형은 [...<변수>]으로 깊은 복사를 할 수 있다.

List

리스트는 아래와 같은 방법들이 있음

List<int> a = [1];

/// 방법1) 배열.toList() 활용
List<int> b = a.toList();

/// 방법2) 전개 연산자(Spread Operator) 활용
List<int> b = [...a];

/// 방법3) 반복문 활용
List<int> b = [for (var i in a) i];

/// 방법4) JSON 직렬화 & 역직렬화 활용
import 'dart:convert';
List<int> b = jsonDecode(jsonEncode(a)).cast<int>();

그러나 2차원 배열을 to.List()로 생성하면 밖에 있는거만 깊은 복사고 안에는 얕게 복사된다.

List<List<int>> a = [[1]];

/// map() & toList() & Spread Operator
List<List<int>> b = a.map((i) => i.toList()).toList();
List<List<int>> b = a.map((i) => [...i]).toList();
List<List<int>> b = [...a.map((i) => i.toList())];
List<List<int>> b = [...a.map((i) => [...i])];

2중 중첩 리스트의 경우는 위와 같은 방법들로 깊은 복사를 할 수 있음

CustomClass

어려움

불변객체


const로 불변객체를 만든다면 얕은 복사를 한 이후 값을 수정하려 한다면 깊은 복사를 강조하기 때문에 메모리 낭비가 없다가 필요할 때 필요한 메모리만 사용할 수 있게 된다.

const로 생성된 객체는 값이 같으면 같은 메모리를 사용하기 때문에 메모리 절약도 된다.

JSON 직렬화, 역직렬화


직렬화(Serialization): 인스턴스를 문자열로 변환하는 과정, 네트워크 통신을 위해서

역직렬화(Deserialization) : 문자열을 인스턴스로 변환하는 과정, 원하는 값을 원할하게 추출하기 위해서

코드 생성기


Flutter freezed Helpers

frf해서 속성추가

dart run build_runner build

위 명령어로 코드 생성

Build runner

좌측 하단의 watch 누르면 된다.

기타


getter, setter, 캡슐화, mixin, extends, extension등에 대해서 학습함.