You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
stringnotificationData=
"""
{
action = "show_pushed_mail";
aps =
{
alert =
{
body = "Compared Exchange Rates are out of tolerance in number of 115.";
subtitle = "[email protected]";
title = "eM Client Licensing";
};
category = "PUSHED_MAIL";
"content-available" = 1;
"mutable-content" = 1;
sound = default;
"thread-id" = "mail_cf73f3bd-1cf9-437c-bc70-4b6bd2b5f7e4";
};
"em-account" = "[email protected]";
"em-account-id" = "cf73f3bd-1cf9-437c-bc70-4b6bd2b5f7e4";
"em-body" = "";
"em-date" = "2024-10-09T01:30:01.0000000Z";
"em-from" = "eM Client Licensing";
"em-from-address" = "[email protected]";
"em-message-path" = "{\n \"Mailbox\": \"INBOX\",\n \"UIDVALIDITY\": \"1117940911\",\n \"UID\": \"317970\",\n \"Message-ID\": \"[email protected]\"\n}";
"em-notification" = Mixed;
"em-notification-id" = 5801afc0ceb977f379adc152333e0d25554a98d4;
"em-subject" = "Compared Exchange Rates are out of tolerance in number of 115.";
"gcm.message_id" = 1728437407395630;
"google.c.a.e" = 1;
"google.c.fid" = eEhP3hWX1U8DuSB9hb3siN;
"google.c.sender.id" = 417058856903;
}
""";vard= NSData.FromString(notificationData);NSPropertyListFormatfmt= NSPropertyListFormat.OpenStep;varuserInfo=(NSMutableDictionary)NSPropertyListSerialization.PropertyListWithData(d,ref fmt,outvar error);varapsKey=new NSString("aps");vardata= userInfo
.Where(kv =>{varr=!kv.Key.ToString().Equals("aps", StringComparison.OrdinalIgnoreCase); apsKey.Dispose();returnr;}).ToDictionary(kv => kv.Key.ToString(),kv => kv.Value.ToString()??string.Empty);
It will reliably crash with ObjectDisposedException which may be quite unexpected. In fact, this is a very reduced example of a problem that was happening in a multi-threaded application where it was even less obvious.
Why does it crash?
We create the NSString object representing the string aps.
When Objective-C enumerates the dictionary keys it reuses the same object, ie. same handle, when enumerating the aps key, and that in turns maps to the same managed NSString object.
Calling Dispose on the NSString causes the managed representation to be invalid and next enumeration of the same key will crash with ObjectDisposedException.
What can we do about it?
Changing the behavior to remove disposed objects from the handle->managed object mapping seems dangerous. (would not help anyway in the original multi-threaded scenario)
Make the Dispose on immutable poolable classes like NSString a no-op? Make an analyzer that warns when someone tries to dispose a NSString instance (would flag the obvious error but not if someone disposes it as NSObject variable)?
Thoughts?
The text was updated successfully, but these errors were encountered:
Consider the following code:
It will reliably crash with
ObjectDisposedException
which may be quite unexpected. In fact, this is a very reduced example of a problem that was happening in a multi-threaded application where it was even less obvious.Why does it crash?
NSString
object representing the stringaps
.aps
key, and that in turns maps to the same managedNSString
object.Dispose
on theNSString
causes the managed representation to be invalid and next enumeration of the same key will crash withObjectDisposedException
.What can we do about it?
Changing the behavior to remove disposed objects from the handle->managed object mapping seems dangerous.(would not help anyway in the original multi-threaded scenario)Make the
Dispose
on immutable poolable classes likeNSString
a no-op? Make an analyzer that warns when someone tries to dispose aNSString
instance (would flag the obvious error but not if someone disposes it asNSObject
variable)?Thoughts?
The text was updated successfully, but these errors were encountered: