1. Operator && functions

  int x = 5;

  x++;
  ++x;
  x--;
  --x;
  x = x + 5;
  x += 5;
  x -= 5;
  x *= 5;
  x ~/= 5;

  bool isEqual = 5 == 10;

  String myString = 'Hello $isEqual';
  print(myString);
  
  
  final myInteger = 5;
  if (myInteger == 10) {
    print("It's ten!");
  } else if (myInteger == 9) {
    print("It's nine!");
  } else if (myInteger > 20) {
    print("Greater than twenty!");
  } else {
    print("Oh, it is something else!");
  }
  
  switch (myInteger) {
    case 10:
      print("It's ten!");
      break;
    case 9:
      print("It's nine!");
      break;
    default:
      print("Oh, it is something else!");
  }
  
  for (int i = 0; i < 10; i++) {
    print(i);
  }
  bool condition = true;
  while (condition) {}

  /*✅ condition이 거짓이 될때까지 실행됨. 조건이 항상 참이 아닌 경우 1번은 실행된다. */
  do {
    print("Hello world");
  } while (condition);
  
  void main(List<String> arguments) {
  String myStringFunc() {
    return "Hello";
  }

  print(myStringFunc());
  print(myStringFunc2());
}
/*✅ scope에 대해서 인지하기*/
String myStringFunc2() {

  myStringFunc1();
  return "Bye";
}

'Flutter' 카테고리의 다른 글

[F] 4. Non-Nullable  (0) 2021.09.03
[F] 3. 변수  (0) 2021.09.03
[F] 2. 프로젝트 시작하기  (0) 2021.09.03
[F] 1. VSC 설정하기  (0) 2021.09.03

1. Null

- 객체에 대한 값의 부재를 나타낸다.

- null인 상태인 객체에 접근을 해야 해당 객체의 프로퍼티에 접근하게 되면 NPE(Null Pointer Exception)이 발생하게 된다.

- NPE는 잘 다루어지지 않으면 runtime 동안 언제 어디서든 일어날 수 있다. 사용자가 경험하게 되는 최악의 경험 -> 앱 삭제 크리를 막기 위해서도 edit-time 단계에서 걸러낼 수 있어야 한다.

- sound null safety를 dart팀은 도입했고, "?"를 타입뒤에 사용하지 않는 이상 해당 객체는 절대로 Null이 될 수 없음을 명시하며, null referece errors를 피할 수 있게 해준다.

2. Dart의 타입시스템

- Nullable types, Non-Nullable types 두개의 타입으로 크게 나눌 수 있을 것이다.

- 예를 들어, String?이라고 명시되어 있다면 해당하는 변수는 String 또는 null을 가지며 이에 모두 해당하지 않는다면 Never가 된다.

- Never에 대한 설명(https://dart.dev/null-safety/understanding-null-safety#never-for-unreachable-code)

참고 자료

https://www.raywenderlich.com/21955673-non-nullable-dart-understanding-null-safety

'Flutter' 카테고리의 다른 글

[F] 5. Operators && functions  (0) 2021.09.03
[F] 3. 변수  (0) 2021.09.03
[F] 2. 프로젝트 시작하기  (0) 2021.09.03
[F] 1. VSC 설정하기  (0) 2021.09.03

1. 변수

void main(List<String> arguments) {
  String myString = 'Hello world';
  int myInteger = 5;
  double myDouble = 5.5;
  /*✅ int와 double은 num을 상속받고 있음. 될 수 있으면 사용하지 않도록..*/
  num myNum = 5;
  myNum = 5.5;

  /*✅ dynamic 될 수 있으면 쓰지 말자*/
  dynamic myAnything = 'Hello';
  myAnything = 5;
  myAnything = 5.5;

  /*✅ 값을 바꾸기 싫을 때, final, 선언과 초기화를 동시에*/
  final int myFinal = 10;
  myFinal = 11;

  /*✅ 선언과 초기화를 따로*/
  int myDigit;
  myDigit = 10;

  /*✅ 타입이 명시 되지 않으면 type inferring*/
  var inferType;
  inferType = 100;
}

'Flutter' 카테고리의 다른 글

[F] 5. Operators && functions  (0) 2021.09.03
[F] 4. Non-Nullable  (0) 2021.09.03
[F] 2. 프로젝트 시작하기  (0) 2021.09.03
[F] 1. VSC 설정하기  (0) 2021.09.03

1.  새로운 프로젝트 시작하기

- cmd + p를 누르고 dart: new project를 선택

- simple version을 선택

- dart_get_up_to_speed로 프로젝트명 입력.

- yaml은 패키지 관리자의 역할을 수행하며 현재 사용중인 버전을 확인할 수 있다.

- analysis_options.yaml에서 아래의 부분을 주석처리 한다.

include: package:pedantic/analysis_options.yaml

- f5를 누르면 실행된 결과를 볼 수 있다.

'Flutter' 카테고리의 다른 글

[F] 5. Operators && functions  (0) 2021.09.03
[F] 4. Non-Nullable  (0) 2021.09.03
[F] 3. 변수  (0) 2021.09.03
[F] 1. VSC 설정하기  (0) 2021.09.03

설치할 익스텐션 목록

- Flutter

- Dart

- Awesome Flutter Snippets

- flutter widget snipp

- flutter code select

- pubspec assist

하나하나 인터넷에서 찾아서 설치하는 과정을 줄일 수 있음.

- version lens

버전의 상태를 보여줌.

- tabout(⭐️⭐️⭐️⭐️⭐️)

써보면 안다..

- exploerer exclude

탐색에서 제외하고 싶은 녀석들을 배제시켜줌.

- todo tree (⭐️⭐️⭐️⭐️⭐️)

comment에서 todo를 통해 내가 작업해야 하는 것들을 표히할 수 있다.

- code spell checker (⭐️⭐️⭐️⭐️⭐️)

타이포로인한 시간낭비는 줄이자.

- bracket pair Colorizer 2(⭐️⭐️⭐️⭐️⭐️)

색상을 통해 scope를 알려준다.

'Flutter' 카테고리의 다른 글

[F] 5. Operators && functions  (0) 2021.09.03
[F] 4. Non-Nullable  (0) 2021.09.03
[F] 3. 변수  (0) 2021.09.03
[F] 2. 프로젝트 시작하기  (0) 2021.09.03

 

1. 들어가기

- 처음 사용하는 사람들은 시작하기 튜토리얼을 참고 하기 바란다.

- terminal에서 아래의 코드를 실행했을때 문제가 없다면 아래의 시작코드를 다운로드 하기 바란다

flutter pub get

시작코드

 

GitHub - ResoCoder/flutter-bloc-library-v1-tutorial: Flutter Bloc Library Tutorial (1.0.0 STABLE)

Flutter Bloc Library Tutorial (1.0.0 STABLE). Contribute to ResoCoder/flutter-bloc-library-v1-tutorial development by creating an account on GitHub.

github.com

2.  Equatable 사용

- 예를 들어, DB에 있는 사용자에 대한 정보를 가져올 때 id만 동일하면 동일한 사용자로 보고 싶을 때 우리는 어떻게 해야 할까?

- 하나의 객체에 연관되어 있는 여러가지의 프로퍼티들 중 특히 id만을 비교하도록 == operator를 구현해주면 될 것이다.

- 그런데 여러개를 해야 한다면? 아주 귀찮다. 그래서 이를 대신해주는 것이 Euqatable패키지이다.

// 1. Equatable를 extends 해준다.
// 2. Euqatable에 커서를 대고 cmd + .을 누르면 패키지를 import 할 수 있다.
// 3. Weather라는 class가 붉은 표시를 낼 것이고, 동일하게 cmd + .를 통해서 override 해준다.
// 4. 나머지 부분을 지우고, 동일한지 확인하고 싶은 부분을 리스트의 elements로 전달한다.

import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';

class Weather extends Equatable {
  final String cityName;
  final double temperatureCelsius;
  final double temperatureFahrenheit;

  Weather({
    @required this.cityName,
    @required this.temperatureCelsius,
    this.temperatureFahrenheit,
  });

  @override
  List<Object> get props => [
        cityName,
        temperatureCelsius,
        temperatureFahrenheit,
      ];
}

 

3. 저장소 자세히 보기

- BLoC은 항상 Repository 레이어와 통신합니다. 통신 이후 새 데이터를 가져올지 아니면 로컬 캐시에서 가져올지를 결정하게 됩니다.

4. BLoC

- Events는 입력

- BLoC이 입력되는 Events에 따라 무엇을 할지 결정

- 그결과 State를 반환

- .yaml파일에 보면 이미 flutter_bloc dependencies가 설치되어 있는 것을 확인할 수 있음.(확실히 하길 원한다면 flutter pub get)

- lib에서 오른쪽 마우스 클릭 -> new bloc 선택 -> bloc명 생성 후 확인

5. Events

- WeatherEvent라는 Abstract class를 활용해 인터페이스 역할을 수행하게 한다.

- 각각의 Events는 WeatherEvent를 Extends하며, 해당 class가 초기화 되었을 때 데이터들을 fetching 할 수 있도록 내부에 usecase를 선언한다.

part of 'weather_bloc.dart';

abstract class WeatherEvent extends Equatable {
  const WeatherEvent();

  @override
  List<Object> get props => [];
}

class GetWeather extends WeatherEvent {
  final String cityName;

  const GetWeather(this.cityName);

  @override
  List<Object> get props => [cityName];
}

class GetDetailedWeather extends WeatherEvent {
  final String cityName;

  const GetDetailedWeather(this.cityName);

  @override
  List<Object> get props => [cityName];
}

 

6. States

- BLoC은 함수처럼 값을 반환하는 방식이아니라 UI를 그리기 위해 필요한 모든 것들을 가지고 있는 States들을 가지고 있다.

- 또한 Events를 추가하거나, States를 청취하는 장소는 구분되어 있다.

- 얼마나 많은 States가 필요할까를 알기 위해 얼마나 다양한 UI가 필요할까?를 생각해 보면 된다.

1. 지역 검색

2. 로딩

3. 데이터 가져오기

4. Error 발생 알리기

class WeatherInitial extends WeatherState {
  const WeatherInitial();

  @override
  List<Object> get props => [];
}

class WeatherLoading extends WeatherState {
  const WeatherLoading();

  @override
  List<Object> get props => [];
}

class WeatherLoaded extends WeatherState {
  final Weather weather;
  const WeatherLoaded(this.weather);

  @override
  List<Object> get props => [weather];
}

class WeatherError extends WeatherState {
  final String message;
  const WeatherError(this.message);
  @override
  List<Object> get props => [message];
}

7. BLoC

- Event와 이에 따른 State를 정의 했다면 이를 연결(?)시키는 파이프 즉, BLoC를 정의할 필요가 있다.

- 특정 이벤트에 따라 우리가 원하는 State로 변환해주면 될일이다.

class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
  final WeatherRepository repository;

  WeatherBloc(this.repository);

  @override
  Stream<WeatherState> mapEventToState(
    WeatherEvent event,
  ) async* {
    yield WeatherLoading();

    if (event is GetWeather) {
      try {
        final weather = await repository.fetchWeather(event.cityName);
        yield WeatherLoaded(weather);
      } on NetworkError {
        yield WeatherError("Couldn't fetch weather. Is the device online?");
      }
    } else if (event is GetDetailedWeather) {
      try {
        final weather = await repository.fetchDetailedWeather(event.cityName);
        yield WeatherLoaded(weather);
      } on NetworkError {
        yield WeatherError("Coulnd't fetch weather. Is the device online?");
      }
    }
  }

  @override
  WeatherState get initialState => throw UnimplementedError();
}

8. BLoC 사용하기

- Widget들은 발생하는 events를 BLoC에 추가하고, BLoC이 반환하는 States에 따라 대응하고 UI를 다시 그리는 작업을 수행하게 된다.

Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Weather App',
      home: BlocProvider(
        builder: (context) => WeatherBloc(FakeWeatherRepository()),
        child: WeatherSearchPage(),
      ),
    );

9. WeatherSearchPage

- starter에는 이미 필요한 widgets은 모두 구현되어 있다.

- states와 대응되는 methods는 buildInitialInput 또는 buildLoading임을 확인하자.

- 다음과 같이 작성하는 경우 Error에 대한 적절한 표시라고 볼 수 없다. 그렇다면 어떻게 할까?

- Snackbar(Error가 발생하면 하단에 warning이 뜨는 형태)를 사용해 보자.

- BlocListener에 대한 이해

- 리스너는 state의 변화 과정마다 오직 1회만 동작한다. 예를 들어, 사용자가 잘못 된 동작에 대해 계속해서 보여주는 것을 원하는 개발자는 없을 것이다.

 child: BlocListener<WeatherBloc, WeatherState>(
          listener: (context, state) {
            if (state is WeatherError) {
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(
                  content: Text(state.message),
                ),
              );
            }
          },
          child: BlocBuilder<WeatherBloc, WeatherState>(
            builder: (context, state) {
              if (state is WeatherInitial) {
                return buildInitialInput();
              } else if (state is WeatherLoading) {
                return buildLoading();
              } else if (state is WeatherLoaded) {
                return buildColumnWithData(context, state.weather);
              }
            },
          ),
        ),
      ),

10. WeatherDetailPage

-  검색 -> submit -> weatherBloc을 얻게 됨.

- master, detail에서 사용하게 됨으로 만들어 진 것을 공유 할 수 있으면 좋겠다~

방법 1. global하게 접근 가능하도록 하기 : main.dart에서 MaterialApp을 BlocProvider로 감싸기

방법 2. search에서 detail 페이지로 해당 BLoC을 다시 주기

방법은 2번 왜냐하면 페이지만 많아지면 globally 접근 가능한 bloc이 많아지면 윽..

 

11. BlocProbiver.value

- 자동으로 dispose 되거나 Stream을 close하지 않기 때문에 생성자가 필요하다. 특히, BlocProvider.value의 생성자는 이미 일반적인 생성자(builder를 통한)내부에서 인스턴스화된 Bloc들에게만 제공된다.

 Navigator.of(context).push(
              MaterialPageRoute(
                builder: (_) => BlocProvider.value(
                  value: BlocProvider.of<WeatherBloc>(context),
                  child: WeatherDetailPage(
                    masterWeather: weather,
                  ),
                ),
              ),
            );

 

12. Adding an event ASAP

- 한번 그려지고 나면 추가적인 작업이 필요 없기 때문에 didChangeDependencies를 활용한다.

- 이를 사용하기 위해서는 StatefulWidget으로 변경할 필요가 있다.

  void didChangeDependencies() {
    super.didChangeDependencies();
    BlocProvider.of<WeatherBloc>(context)
      ..add(GetDetailedWeather(widget.masterWeather.cityName));
  }
  
  
  child: BlocBuilder<WeatherBloc, WeatherState>(
          builder: (context, state) {
            if (state is WeatherLoading) {
              return buildLoading();
            } else if (state is WeatherLoaded) {
              return buildColumnWithData(context, state.weather);
            }
          },
        ),

 

13 완성 코드 -----> https://github.com/taeskim-42/DDD.git

 1. Process의 communication state

- independent: 개별 프로세스가 동작하는 상황

- cooperating: share data, context switch, communication의 방식 중요

2. how to communicate( == IPC(Inter-Process Communication))

- 데이터를 주고 받는 것(Send, Receive)

- shared memory, message passing

3. 둘은 어떤 특징들을 가지고 있을까?

1) shared memory의 특징

- 메모리에 접근해서 데이터를 직접 다룬다.

- buffer를 통해서 communication하게 된다.

- buffer의 상태에 따라 3가지 경우로 나뉜다.

- 가득 찬 경우: P(생산 프로세스) 기다리기 - Q(소비 프로세스) 소비

- 넉넉한 경우: P 생산 - Q 소비

- 없는 경우: P 생산 - Q 기다리기

2) shared memory의 비유

- 하나의 테이블에 다양한 정보들(문서, 도구, 차트 등등..)이 있고, 이것을 활용해 정보를 생산하고 소비하게 된다.

- 각각의 사람들(프로세스)가 동시에 정보에 접근해서 변경을하게 되면, 혼란스럽게 될 수 있는 확률이 크다.

3) message passing의 특징

- 메시지만 주고 받는다.

- O/S가 cooperating 할 수 있는 도구(mailbox)를 제공한다.

- direct :메시지를 받을 프로세스를 명시한다.ex) Send(Q, message), Receive(P, message)

- indirect: 메시지를 mailbox에 넣어 둔다. ex) A == 메일박스, Send(A, message), Receive(P, message)

- Blocking send, Blocking receive: synchronous

- Non-blocking send, Non-blocking receive: asynchronous

4) message passing의 비유

- 각자의 책상에 앉아 있고 종이에 메시지를 적어 다른 책상에 앉아 있는 사람에게 전달한다.

- 또는 각자의 책상에 앉아 있고, 종이에 메시지를 적어 메일함에 넣어두면 누군가가 가져간다.

'OS' 카테고리의 다른 글

[공룡책] Chapter 2. Process? (1/4)  (0) 2021.07.13
[공룡책] Chapter 1. 운영체제는 무엇인가?  (0) 2021.07.12

1. 프로세스

- 프로세스는 실행 중인 프로그램(메모리에 올려 저서 작동하고 있는 상태), 프로세스는 os에서 작업 단위

- os는 프로세스를 관리하는 프로그램이다.

- 이와 같은 작업을 수행하기 위해서 프로세스는 리소스가 필요하며 이는, CPU time, memory, files, I/O devices

- 프로세스는 여러개의 메모리 레이아웃으로 나눌 수 있다.

2.  메모리 구조

  argv, argc 실행파일에서 입력되는 값
  stack auto
    가변 구간
  heap 사용자 활용 영역( malloc )
data segment bss uninitialized data
data initialized data
  text 코드 또는 literal

- 프로세스의 생명주기

1) new: 프로세스가 만들어지는 중

2) ready: 프로세스가 cpu에 할당되길 기다리는 중

3) running: Instruction들이 실행되는 중

4) waiting: 프로세스가 이벤트가 발생하길 기다리는 중

5) terminated: 프로세스의 실행이 종료되는 중

 

3.  pcb

- 각각의 프로세스는 pcb라는 구조체에 의해 대변되며, 담기는 정보는 아래와 같다.

1) Process state - new, ready, running, waiting, terminated

2) Program counter - Instruction으로 가져올 메모리 주소를 저장하는 곳

3) CPU registers - IR(instruction register), DR(data register)

4) CPU-scheduling information - cpu를 주고 받기 위한 스케쥴링 정보들

5) Memory-management information - 메모리 alloc과 관련된 정보

6) Accounting information - 계정 정보

7) I/O status information - 어떤 파일을 오픈했고 사용했는지

- 프로그램은 싱글 스레드에서 실행됨( only one task at a time )

- 현대의 os는 프로세스의 개념을 확장해왔으며 이는 한번에 한가지 이상의 작업을 실행할 수 있도록 함.

- Thread는 lightweight process. (위의 thread는 한줄로 쭉 이어져 실행되는 개념인 반면, os가 pcb를 통해 여러개의 프로세스를 운영하듯, process 안에서도 여러개의 thread를 운영한다는 개념적 이해를 필요로 한다.)

4. Process Scheduling

- Multiprogramming : 동시에 여러개의 프로그램을 실행시켜보자. cpu 사용량을 최대화 하기 위해

- time sharing : cpu core를 프로세스간의 변경을 통해 사용자 입장에서는 동시에 작동하는 것처럼 보이도록 함.

- ready queue는 링크드 리스트로 구현한다.

5. Queueing Diagram

- 프로세스 스케쥴링은 일반적인 표현

- cpu가 running하는 과정에서 interupting 되는 경우 context가 switch 된다.

- 프로세스가 사용되고 있는 상태를 context라고 하며, context에는 program count, cpu registers(ir, dr)이 포함된다.

- 이와 같은 정보는 PCB에 표현되며, 프로세스가 변경되는 context switch로 인해 총 3가지 task가 실행된다.

1) cpu core를 다른 process로 변경

2) 현재 process의 상태 저장

3) 다른 process의 상태 재개

- 이를 표현하면 아래와 같다.

6. Operations on Processes

- os는 프로세스를 만들거나 종료할 수 있는 메커니즘을 제공해야 한다.

- 하나의 프로세스는 다양한 새로운 프로세스를 만들 수 있다.

- 만드는 프로세스를 parent process, 만들어진 프로세스를 child process

- 실행의 2가지 방식

1) children과 함께 concurrently 실행

2) children이 종료 될때까지 기다리기

- 주소 공간의 2가지 사용 방식

1) 부모의 프로세스를 복사

2) 새로운 프로그램에서 실행(?)

7. 좀비와 고아..(ㅠ_ㅜ)

- 좀비 : 자식 프로세스가 terminated() 되었지만 부모 프로세스가 종료 상태를 회수 하지 않음(wait() 시스템 콜을 통해), 즉, 아이가 먼저 하늘나라로 갔는데(exit()) 부모가 장례(wait())를 치르지 않음..( 잔인. ㅠㅜ)

- 고아: 부모 프로세스가 먼저 terminated() 되었지만 자식프로세스 고아가 됨..

- wait()함수는 child의 상태 변화를 기다린다.

- child의 상태: 종료, 멈춤, 재시작

- 특히, child가 종료 되면 wait()함수는 시스템이 사용했던 리소스들을 회수하도록 허락한다. 반환값은 child의 pid이다.

'OS' 카테고리의 다른 글

[공룡책] Chapter 2. Process (3/4)  (0) 2021.07.15
[공룡책] Chapter 1. 운영체제는 무엇인가?  (0) 2021.07.12

+ Recent posts