Make sure that the NSString which represents keys in a NSDictionary is always the same value, by caching the string to NSString conversion in a dictionary

This commit is contained in:
Frederik Carlier
2016-11-24 00:24:12 +01:00
parent 6c95260157
commit 8dc5f8ba24
2 changed files with 26 additions and 6 deletions

View File

@@ -291,7 +291,7 @@ namespace Claunia.PropertyList
{ {
idMap.Add(obj); idMap.Add(obj);
} }
else if(!this.ReuseObjectIds && obj is NSString && !IsSerializationPrimitive((NSString)obj)) else if (!this.ReuseObjectIds && obj is NSString && !IsSerializationPrimitive((NSString)obj))
{ {
idMap.Add(obj); idMap.Add(obj);
} }
@@ -314,9 +314,9 @@ namespace Claunia.PropertyList
var first = idMap.OfType<UID>().First(v => NSObject.ArrayEquals(v.Bytes, uid.Bytes)); var first = idMap.OfType<UID>().First(v => NSObject.ArrayEquals(v.Bytes, uid.Bytes));
return idMap.IndexOf(first); return idMap.IndexOf(first);
} }
else if (!this.ReuseObjectIds && obj is NSArray) else if (!this.ReuseObjectIds && (obj is NSArray || (obj is NSString && !IsSerializationPrimitive((NSString)obj))))
{ {
int index = 0; int index = -1;
for (int i = 0; i < idMap.Count; i++) for (int i = 0; i < idMap.Count; i++)
{ {
@@ -327,6 +327,11 @@ namespace Claunia.PropertyList
} }
} }
if (index == -1)
{
throw new InvalidOperationException();
}
return index; return index;
} }
else else

View File

@@ -45,12 +45,17 @@ namespace Claunia.PropertyList
{ {
readonly Dictionary<string, NSObject> dict; readonly Dictionary<string, NSObject> dict;
// Maps the keys in this dictionary to their NSString equivalent. Makes sure the NSString
// object remains constant accross calls to AssignIDs and ToBinary
readonly Dictionary<string, NSString> keys;
/// <summary> /// <summary>
/// Creates a new empty NSDictionary. /// Creates a new empty NSDictionary.
/// </summary> /// </summary>
public NSDictionary() public NSDictionary()
{ {
dict = new Dictionary<string, NSObject>(); dict = new Dictionary<string, NSObject>();
keys = new Dictionary<string, NSString>();
} }
/// <summary> /// <summary>
@@ -366,7 +371,7 @@ namespace Claunia.PropertyList
foreach (KeyValuePair<string, NSObject> entry in dict) foreach (KeyValuePair<string, NSObject> entry in dict)
{ {
new NSString(entry.Key).AssignIDs(outPlist); keys[entry.Key].AssignIDs(outPlist);
} }
foreach (KeyValuePair<string, NSObject> entry in dict) foreach (KeyValuePair<string, NSObject> entry in dict)
@@ -380,7 +385,7 @@ namespace Claunia.PropertyList
outPlist.WriteIntHeader(0xD, dict.Count); outPlist.WriteIntHeader(0xD, dict.Count);
foreach (KeyValuePair<String, NSObject> entry in dict) foreach (KeyValuePair<String, NSObject> entry in dict)
{ {
outPlist.WriteID(outPlist.GetID(new NSString(entry.Key))); outPlist.WriteID(outPlist.GetID(keys[entry.Key]));
} }
foreach (KeyValuePair<String, NSObject> entry in dict) foreach (KeyValuePair<String, NSObject> entry in dict)
{ {
@@ -488,6 +493,7 @@ namespace Claunia.PropertyList
public void Add(string key, NSObject value) public void Add(string key, NSObject value)
{ {
dict.Add(key, value); dict.Add(key, value);
keys.Add(key, new NSString(key));
} }
/// <summary> /// <summary>
@@ -516,6 +522,7 @@ namespace Claunia.PropertyList
/// <param name="key">Key.</param> /// <param name="key">Key.</param>
public bool Remove(string key) public bool Remove(string key)
{ {
keys.Remove(key);
return dict.Remove(key); return dict.Remove(key);
} }
@@ -534,7 +541,7 @@ namespace Claunia.PropertyList
/// Gets or sets the <see cref="Claunia.PropertyList.NSObject"/> at the specified index. /// Gets or sets the <see cref="Claunia.PropertyList.NSObject"/> at the specified index.
/// </summary> /// </summary>
/// <param name="index">Index.</param> /// <param name="index">Index.</param>
public NSObject this [string index] public NSObject this[string index]
{ {
get get
{ {
@@ -542,6 +549,11 @@ namespace Claunia.PropertyList
} }
set set
{ {
if (!keys.ContainsKey(index))
{
keys.Add(index, new NSString(index));
}
dict[index] = value; dict[index] = value;
} }
} }
@@ -579,6 +591,7 @@ namespace Claunia.PropertyList
/// <param name="item">Item.</param> /// <param name="item">Item.</param>
public void Add(KeyValuePair<string, NSObject> item) public void Add(KeyValuePair<string, NSObject> item)
{ {
keys.Add(item.Key, new NSString(item.Key));
dict.Add(item.Key, item.Value); dict.Add(item.Key, item.Value);
} }
@@ -587,6 +600,7 @@ namespace Claunia.PropertyList
/// </summary> /// </summary>
public void Clear() public void Clear()
{ {
keys.Clear();
dict.Clear(); dict.Clear();
} }
@@ -618,6 +632,7 @@ namespace Claunia.PropertyList
/// <returns><c>true</c> if successfully removed, <c>false</c> if not, or if item is not in current instance.</returns> /// <returns><c>true</c> if successfully removed, <c>false</c> if not, or if item is not in current instance.</returns>
public bool Remove(KeyValuePair<string, NSObject> item) public bool Remove(KeyValuePair<string, NSObject> item)
{ {
keys.Remove(item.Key);
return dict.Remove(item.Key); return dict.Remove(item.Key);
} }