-
Notifications
You must be signed in to change notification settings - Fork 516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Disposing immutable objects can lead to unpredictable behavior when Objective-C runtime does object pooling #21425
Comments
This is a tricky problem, and we've run into different variations on it over the years.
The problem with this is that I can certainly envision someone wanting to dispose at least some One idea I just had would be to just skip disposing tagged pointers, but the main problem with this approach is that there's no reliable way to detect tagged pointers (Apple can change their implementation at any time). Just doing a string comparison on the Objective-C class ( |
Presumably, if this is affecting all tagged objects, we can differentiate by the lowest (x64) / highest (arm64) bit == 1 and disallow I'm not sure if there are any other cases of reused objects aside from the tagged ones. |
That internal implementation detail changed in iOS 14: "Let's explore one more change coming this year. A change to the tagged pointer format on arm64." - https://developer.apple.com/videos/play/wwdc2020/10163/ Which means we'll have to detect (and not apply the tagged pointer logic) when running on iOS 13 or earlier (our min iOS is right now iOS 12.2 in .NET 9). Alternatively not enable it when an app's min OS version is <14. |
I think the part about the tagging logic that changed doesn't affect the "is tagged" bit, only the other ones which we do not rely on. |
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: