Dart 언어 관련 기초적인 정리

다른 언어도 마찬가지지만 아주 기본적인 개념이지만 쉽게 까먹거나 정리를 잘 안하고 넘어가는 것들이 있습니다.

이런것들을 한번 개념정리 해봅시다.

dynamic vs var

var a = 1;
a = "Hello"; // ERROR
dynamic b = 1;
b = "Hello"; // OK
  • var : 불분명한 타입이지만 한번 선언된 타입을 바꾸면 안됩니다.
  • dynamic : 타입을 바꿀 수 있습니다.

JavaScript의 변수와 비슷한건 dynamic이라고 할 수 있겠네요. 추측건데 저장비용이나 연산비용은 후자가 더 많을 것 같습니다.

final vs const vs static

먼저 final 과 const의 차이점을 알아봅시다. 간단하죠~

const int a = 1; // OK
const int b = getOne(); // ERROR
final int c = 2; // OK
final int d = getTwo(); // OK
  • 공통점 : 둘다 처음에 결정된 값을 바꾸지 못합니다.
  • 차이점 : const는 컴파일 전에 값을 결정, final은 런타임시에 값을 결정해도 됩니다.

당연히 이것도 저장비용, 연산비용에 차이점에 있으니까 고대부터 다르게 존재해 왔겠죠?

그럼 static은 무엇이냐?

class Aclass {
  static int B = 1;
  get getB => B;
  int addB() => B++;
}

void main() {
  var a1 = Aclass();
  var a2 = Aclass();
  a2.addB();
  print(a1.getB);
  print(a2.getB);
  print(Aclass.B);
  print(Aclass.getB); // ERROR
}
  • static 으로 선언하면 해당 클래스로 선언된 모든 오브젝트에 공통으로 적용됩니다.
  • 심지어 클래스명 자체로 접근도 가능하죠.
  • 일종의 같은 클래스끼리의 전역변수로 사용할 수 있습니다.

Future vs Stream

  • Future는 JavaScript에서 async/await를 생각하면 됩니다. 실행이 완료될 때 까지 기다립니다.
  • Stream은 yield를 이용해서 특정 변수를 리턴함으로써, 중간과정에서 이벤트를 발생시킵니다.
  • Flutter에서 시간에 따른 UI 변화를 줘야 할 때 두 기능을 이용한 FutureBuilder, StreamBuilder를 사용하게 됩니다. 이때 용도도 그 정의에 따라서 달라집니다.
    • FutureBuilder : 뭔가 값이 완성될 때 까지 뺑뺑이를 돌리다가 값이 완성되면 UI 표출 할 때 사용
    • StreamBuilder : 초시계처럼 특정순간 마다 값이 바뀔때 사용

Flutter VS Native 메모리 사용량 비교

지난번 포스팅에서 Flutter DevTools을 이용하면서 제가 만든 앱의 메모리 사용량이 너무 과도하다는 점을 확인했었습니다. 별거 아닌 테스트용 앱인데도 카카오톡의 사용량을 능가하는게 너무 이상했었죠.

IntelliJ Idea에서 Flutter App 성능 프로파일링 하기

그래서 오늘은 프로젝트를 막 생성했을 때. 즉 초기상태의 Hello World 앱만 가지고 Flutter와 Native 앱의 메모리 사용량 비교를 해보았습니다. 다 읽는데 5분도 안걸려요~

먼저 Flutter 입니다. 이런 앱이에요. 만들면 바로 나오는거…

이미지1

160MB나 할당되어 있네요. 인스타그램이 300인데.. 지까지것이 뭐라고… ㄷㄷㄷ

이미지1

이번에는 Native 앱입니다. 이런 앱입니다. 생김새는 다르지만 하는일은 크게 다르지 않은 초기상태의 Hello World 앱이에요.

이미지1

보이시나요? hello_world_flutter와 hello_word_native(?) 의 메모리 차이가~ 앱 이름에 ‘l’자 하나 안들어갔다고 3배 차이가 나고 있네요. (아이고 이놈의 오타)

이미지1

여기저기서 아티클을 검색해서 보니까 어쩔수 없는 차이가 있는것 같네요. 아무래도 flutter로 계속 개발하려면 메모리 최적화에 신경 안쓸수가 없을것 같아요. 할당되는 메모리양(RSS) 줄이는것도 방법이 있다면 찾아보려고 합니다. 방법이 있다면 공유하도록 하겠습니다.

Flutter sqflite 사용시 컬럼이 없을 경우 추가하기

sqlite에서

pragma table_info(테이블이름)

으로 쿼리를 날리면 컬럼정보가 아래와 같은 유형으로 나타납니다. 그렇기 때문에 맵 리스트로 저장 되었을 때 name을 기준으로 비교해서 존재여부를 판단하면 됩니다.

이미지1

이걸 flutter에서 sqflite를 사용할 때 alter table을 사용하기 위해서는 아래와 같은 사용예를 들 수 있습니다.

List<Map> res = await db.rawQuery("PRAGMA table_info(테이블네임)", null);
bool hasColumn = false;
for(int i = 0 ; i < res.length; i++) {
  if (res[i]["name"] == "컬럼네임") {
    hasColumn = true;
  }
}
if (!hasColumn) {
  await db.execute('''
    ALTER TABLE 테이블네임 ADD 컬럼네임 INTEGER DEFAULT 0 NOT NULL
  ''');
}