LoginSignup
3
1

More than 5 years have passed since last update.

PlayerPrefs.GetString()のdefaultValueにnull入れると空文字が出てくる

Last updated at Posted at 2019-01-12

どういうこと?

以下のコードを見てください。

PlayerPrefs.DeleteAll();

const string key = "KeyOfTheTwilight";
var value = PlayerPrefs.GetString(key, null);

Debug.Log("key:" + PlayerPrefs.HasKey(key));
Debug.Log("value:" + value);
Debug.Log("length:" + value.Length);

予想

PlayerPrefsは設定とかを保存しておくクラスです。
DeleteAll()はその名の通り保存された設定値すべてが消えます。
公式ドキュメントにはこうあります。

PlayerPrefs.GetString
キーが存在する場合、key に対応する値を取得します。
キーが存在しない場合、defaultValue を返します。

つまりこの場合はvalueはdefaultValueであるnullであり、value.Lengthで長さを取得しようとしたところでご存知NullReferenceExceptionが出てしまう……はずです。

と思うじゃん?

スクリーンショット 2019-01-13 2.35.04.png
???

value = null;
Debug.Log("length:" + value.Length);

スクリーンショット 2019-01-13 2.37.16.png
?????

キーが存在しないからdefaultValueが返るはず。
defaultValueはnull
nullならNullReferenceExceptionが出るはず。

つまりdefaultValueをnullに設定したにもかかわらず空文字が返ってきている。

!!!!結!!!論!!!!

PlayerPrefs.GetString

キーが存在する場合、key に対応する値を取得します。
キーが存在しない場合、defaultValue を返します。

キーが!!!!!!存在しない!!!!!!場合!!!!defaultValueを!!!!!!!返します!!?!!??!!?!うそつき!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

実験と推論

実験

実験1:int, floatなどstringではない型として保存した値を取得
実験1

PlayerPrefs.SetInt(key, 193);
PlayerPrefs.Save();
var value = PlayerPrefs.GetString(key, null);
実験2:nullを保存
実験2
PlayerPrefs.SetString(key, null);
PlayerPrefs.Save();
var value = PlayerPrefs.GetString(key, null);

実験1、2ともに空文字が返ってきます。

推論

PlayerPrefs.csは各Platformに深く依存しているクラスなので中身を見ることはできませんが、c#層の実装を見ることで原因を推測することはできます。

PlayerPrefs.cs
/// <summary>
///   <para>Returns the value corresponding to key in the preference file if it exists.</para>
/// </summary>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern string GetString(string key, string defaultValue);

/// <summary>
///   <para>Returns the value corresponding to key in the preference file if it exists.</para>
/// </summary>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
public static string GetString(string key)
{
return PlayerPrefs.GetString(key, "");
}

推測ですが……本当に根拠もなにもない推測なんですが、PlayerPrefsの考える「値がないstring」は""であってnullではない……?

ほんとうの結論

string.IsNullOrEmpty()使おう!

PlayerPrefsにJSONを保存してMiniJSONでデシリアライズして……とやってる最中にこれが起きたため、要因を他に求めてドハマリしました。
なにげにUnityEditorはいったん終了させてもPlayerPrefsは保存されたままとか知らなかった……。

UnityEditor / unity 2018.3.0
上の環境でしか確認していないですが、UnityのバージョンとかPlatformによって動作が違ったらもっとムカつくので確認はしていません。

おしまい。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1