Skip to content
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

objc_getClassList crashed with an iOS 16 available class, in device that lower than iOS 16 #61215

Open
kemchenj opened this issue Sep 21, 2022 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@kemchenj
Copy link

kemchenj commented Sep 21, 2022

Describe the bug

objc_getClassList crash in the code below:

#if canImport(RoomPlan)

import RoomPlan

@available(iOS 16, *)
class Foo: NSObject {
  var bar: CapturedRoom?
}

#endif

import SwiftUI

@main
struct MetadataAccessorCrashApp: App {
  var body: some Scene {
    WindowGroup {
      Text("")
        .onAppear {
          // Crash here
          let _ = objc_getClassList(nil, 0)
        }
    }
  }
}

Steps To Reproduce
Steps to reproduce the behavior:

  1. Clone the repository https://github.com/kemchenj/TypeMetadataAccessorCrash
  2. Open MetadataAccessorCrash.xcodeproj project
  3. Build and run on any iOS simulator or device that OS version lower than iOS 16 (e.g. iOS 15.5)
  4. App will crash when objc_getClassList was called

Expected behavior

Not crash.

Screenshots

Stacktrace:

Screen Shot 2022-09-21 at 09 11 10

Environment (please fill out the following information)

  • OS: macOS
  • Xcode 14.0

Additional context

@kemchenj kemchenj added the bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. label Sep 21, 2022
@theblixguy
Copy link
Collaborator

CC @mikeash

@mikeash
Copy link
Contributor

mikeash commented Sep 21, 2022

This is, unfortunately, a known problem. The ObjC runtime doesn't know about the limited availability and tries to instantiate the class even though it won't work on the older OS version.

If possible, avoid objc_getClassList and objc_copyClassList. In addition to this problem, they're extremely inefficient and it's usually better to maintain an explicit list of the classes you're interested in.

It's also possible to work around this problem by adding an unused generic parameter to the class. @available(iOS 16, *) class Foo<T>: NSObject will hide it from the ObjC runtime so it will no longer try to instantiate Foo.

@kemchenj
Copy link
Author

This is, unfortunately, a known problem. The ObjC runtime doesn't know about the limited availability and tries to instantiate the class even though it won't work on the older OS version.

If possible, avoid objc_getClassList and objc_copyClassList. In addition to this problem, they're extremely inefficient and it's usually better to maintain an explicit list of the classes you're interested in.

It's also possible to work around this problem by adding an unused generic parameter to the class. @available(iOS 16, *) class Foo<T>: NSObject will hide it from the ObjC runtime so it will no longer try to instantiate Foo.

Ok, look likes I should go with the generic parameter way. Thanks for your explanation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

3 participants