LoginSignup
1

More than 3 years have passed since last update.

posted at

updated at

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

どういうこと?

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

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によって動作が違ったらもっとムカつくので確認はしていません。

おしまい。

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
What you can do with signing up
1