Unity 6.5의 `AutoStaticsCleanup`과 `NoAutoStaticsCleanup`은 뭐가 다를까?

개발 이모저모

목록 보기
4/7
post-thumbnail

Unity 6.5를 보다 보면 이런 Attribute가 보인다.

[AutoStaticsCleanup]

이건 이름만 봐도 어느 정도 이해가 된다.

static 값을 자동으로 정리해주는 기능이구나.

그런데 반대로 이런 것도 있다.

[NoAutoStaticsCleanup]

처음 봤을 때 조금 이상했다.

아니... NoAutoStaticsCleanup을 안 붙이면 원래 자동 Cleanup 안 하는 거 아닌가?

실제로 간단한 코드만 보면 그렇게 느껴진다.


먼저 Domain Reload부터

Unity에서 Enter Play Mode Options를 사용하면서 Reload Domain을 끄면 Play Mode에 들어갈 때마다 C# Domain을 새로 만들지 않는다.

덕분에 Play Mode 진입 속도는 빨라지지만 한 가지 문제가 생긴다.

바로 static 값이 그대로 남을 수 있다는 것이다.

예를 들어:

public static int Count = 0;

게임 실행 중에

Count = 100;

이 되었다고 해보자.

Domain Reload가 켜져 있다면 다음 Play Mode에서 다시

Count = 0

으로 시작한다.

하지만 Domain Reload를 꺼놓은 경우에는 이전 static 값이 그대로 남을 수 있다.

첫 번째 Play
Count = 0

↓ 실행 중

Count = 100

↓ Stop
↓ 다시 Play

Count = 100

개발 중에는 상당히 귀찮은 문제가 될 수 있다.


AutoStaticsCleanup

Unity 6.5에서는 이런 static 값을 자동으로 초기화하기 위해 AutoStaticsCleanup을 사용할 수 있다.

[AutoStaticsCleanup]
public static int Count = 0;

이렇게 선언하면 Unity가 해당 static을 자동 Cleanup 대상으로 관리한다.

그래서 Domain Reload를 꺼놓더라도 다시 Play Mode에 들어가면 초기값으로 돌아간다.

첫 번째 Play
Count = 0

↓ 실행 중

Count = 100

↓ Stop
↓ 다시 Play

Count = 0

즉 간단하게 생각하면:

AutoStaticsCleanup = Domain Reload 없이도 static을 초기 상태로 돌려줘.

라고 보면 된다.


그런데 NoAutoStaticsCleanup은 왜 있는 걸까?

여기서 조금 의문이 생긴다.

public static int Count;

이렇게 그냥 선언한 static도 기본적으로 AutoStaticsCleanup 대상이 아니다.

그런데 굳이

[NoAutoStaticsCleanup]
public static int Count;

라고 적어야 할 이유가 있을까?

결론부터 말하면,

단독으로 사용하면 런타임 결과는 거의 같아 보인다.

public static int A = 0;

[NoAutoStaticsCleanup]
public static int B = 0;

Domain Reload가 꺼진 상태라면 둘 다 이전 값을 유지할 수 있다.

NoAutoStaticsCleanup이 값을 유지시키기 위해 별도의 작업을 하는 것은 아니다.

그럼 왜 존재할까?


1. 상위 AutoStaticsCleanup 정책에서 제외할 수 있다

가장 중요한 이유다.

AutoStaticsCleanup은 static 필드 하나하나뿐 아니라 타입 전체에 적용할 수도 있다.

예를 들어:

[AutoStaticsCleanup]
public partial class GameStatics
{
    public static int Score = 0;
    public static int Coin = 0;
    public static int UniqueId = 0;
}

이렇게 하면 해당 타입 안에 있는 static들이 자동 Cleanup 대상이 된다.

대략 이런 느낌이다.

GameStatics
├─ Score       → Cleanup
├─ Coin        → Cleanup
└─ UniqueId    → Cleanup

그런데 UniqueId만 초기화하고 싶지 않다면?

이때 NoAutoStaticsCleanup을 사용할 수 있다.

[AutoStaticsCleanup]
public partial class GameStatics
{
    public static int Score = 0;

    public static int Coin = 0;

    [NoAutoStaticsCleanup]
    public static int UniqueId = 0;
}

결과적으로:

GameStatics
├─ Score       → Cleanup
├─ Coin        → Cleanup
└─ UniqueId    → Cleanup 제외

가 된다.

즉 이 상황에서는 NoAutoStaticsCleanup이 확실한 역할을 한다.

상위에서 적용된 Auto Cleanup 정책을 특정 멤버에서 예외 처리한다.


2. "일부러 Cleanup 안 하는 거야"라는 의도를 표현한다

또 하나 중요한 부분이 있다.

다음 코드를 보자.

public static int PersistentCounter;

코드만 봐서는 이 static이

  • 실수로 Cleanup 설정을 빼먹은 건지
  • 의도적으로 값을 유지하려는 건지

알기 어렵다.

그런데 이렇게 작성하면 이야기가 달라진다.

[NoAutoStaticsCleanup]
public static int PersistentCounter;

이제 코드를 보는 사람 입장에서는 바로 이해할 수 있다.

아, 이 값은 의도적으로 자동 초기화를 하지 않는구나.

NoAutoStaticsCleanup은 단순히 동작을 바꾸는 Attribute라기보다 정책을 명시하는 역할도 가지고 있다.

Unity의 Static Cleanup 관련 Analyzer를 사용하는 경우에는 이런 구분이 더 중요해진다.


그러면 아무것도 안 붙이는 것과 뭐가 다른가?

간단히 정리하면 다음과 같다.

선언의미
Attribute 없음별도의 Cleanup 정책을 지정하지 않음
[AutoStaticsCleanup]자동으로 초기화함
[NoAutoStaticsCleanup]의도적으로 자동 초기화하지 않음

특히 아래 두 코드는 실행 결과만 보면 비슷할 수 있다.

static int Value;
[NoAutoStaticsCleanup]
static int Value;

하지만 코드가 표현하는 의미는 다르다.

첫 번째는

아무 설정도 하지 않았다.

이고,

두 번째는

이 static은 일부러 Cleanup하지 않는다.

라는 의미다.


개인적으로 이해한 방식

처음에는 이름 때문에

[NoAutoStaticsCleanup]

을 붙이면 Unity가 무언가 특별하게 "값을 보존하는 작업"​을 해주는 줄 알았다.

하지만 실제로는 그보다는

AutoStaticsCleanup
→ 이 static은 자동 초기화해라.

NoAutoStaticsCleanup
→ 이 static은 자동 초기화 대상에서 명시적으로 제외해라.

라는 정책 선언에 가깝다.

특히 클래스 전체에 AutoStaticsCleanup을 적용하고 일부 static만 예외 처리할 때 의미가 명확해진다.


정리

NoAutoStaticsCleanup만 단독으로 보면

이거 그냥 Attribute 안 붙이는 거랑 똑같은 거 아닌가?

라는 생각이 드는 게 자연스럽다.

실제 런타임 결과도 비슷할 수 있다.

하지만 존재 이유는 분명하다.

  • 상위 AutoStaticsCleanup 정책에서 특정 static을 제외할 수 있다.
  • Analyzer에게 의도적으로 Cleanup하지 않는다는 것을 알려줄 수 있다.
  • 코드만 봐도 static의 수명 정책을 명확하게 표현할 수 있다.

결국 한 줄로 정리하면:

NoAutoStaticsCleanup은 static 값을 유지시키는 기능이라기보다는, "이 static은 자동 Cleanup하지 않는다"는 것을 명시적으로 선언하기 위한 Attribute다.

그래서 프로젝트에서 Static Cleanup 정책을 명확하게 관리한다면, 단순히 Attribute를 생략하는 것과는 꽤 다른 의미를 가진다.

profile
유니티를 통한 스페셜 테크닉만 다루는 독특한 개발자

0개의 댓글