Cannot Find Child Class Of An @objc Class

by ADMIN 42 views

Introduction

When working with Objective-C and Swift classes, it's not uncommon to encounter issues with class visibility and accessibility. In this article, we'll explore a specific problem where a child class of an @objc class cannot be found, even though the parent class is present in the output file. We'll delve into the possible causes and provide a step-by-step guide to reproduce the issue.

What Happened?

Let's start with the scenario described in the original issue:

  • We have an @interface SheetVC: UIViewController in Objective-C.
  • We have a Swift class @objc open class BaseSheetVC: SheetVC.
  • Both classes can be found in the output file using the ipsw class-dump command.
  • However, when we define another class final class ChildSheetVC: BaseSheetVC, it cannot be found.

Reproducing the Issue

To reproduce this issue, follow these steps:

  1. Create a new Objective-C class SheetVC that inherits from UIViewController:

#import <UIKit/UIKit.h>

@interface SheetVC : UIViewController

@end


2.  Create a new Swift class `BaseSheetVC` that inherits from `SheetVC` and is marked as `@objc`:

    ```swift
@objc open class BaseSheetVC: SheetVC {
    // Class implementation
}
  1. Verify that both classes can be found in the output file using the ipsw class-dump command:

ipsw class-dump --arch arm64 --all --demangle machO > output.json


4.  Create a new Swift class `ChildSheetVC` that inherits from `BaseSheetVC`:

    ```swift
final class ChildSheetVC: BaseSheetVC {
    // Class implementation
}
  1. Run the ipsw class-dump command again and verify that ChildSheetVC is not present in the output file.

Possible Causes

There are several possible causes for this issue:

  • Accessibility: The @objc attribute is used to make the class accessible to Objective-C. However, this attribute only applies to the class itself, not its subclasses. Therefore, even though BaseSheetVC is marked as @objc, its subclass ChildSheetVC may not be accessible.
  • Visibility: The final keyword in Swift indicates that a class cannot be subclassed. However, this keyword only applies to the class itself, not its subclasses. Therefore, even though ChildSheetVC is marked as final, it may still be accessible to Objective-C.
  • Compilation: The issue may be caused by a compilation error or a missing dependency. Verify that the Swift class is compiled correctly and that all dependencies are present.

Conclusion

In conclusion, the issue of a child class of an @objc class not being found can be caused by a combination of factors, including accessibility, visibility, and compilation. By following the steps outlined in this article, you can reproduce the issue and investigate the possible causes. Remember to verify that the Swift class is compiled correctly and that all dependencies are present.

Additional Tips

  • Use the @objc attribute: When creating a Swift class that needs to be accessible to Objective-C, use the @objc attribute to make it visible.
  • Verify class visibility: Use the ipsw class-dump command to verify that the class is present in the output file.
  • Check for compilation errors: Verify that the Swift class is compiled correctly and that all dependencies are present.

ipsw Version

The ipsw version used in this article is:

3.1.560

Search

  • [x] I did search for other open and closed issues before opening this.

Code of Conduct

  • [x] I agree to follow this project's Code of Conduct.

Additional Context

Introduction

In our previous article, we explored the issue of a child class of an @objc class not being found, even though the parent class is present in the output file. In this article, we'll provide a Q&A section to help you better understand the issue and its possible causes.

Q: What is the @objc attribute?

A: The @objc attribute is used to make a Swift class accessible to Objective-C. This attribute only applies to the class itself, not its subclasses.

Q: Why is my child class not being found?

A: There are several possible causes for this issue, including:

  • Accessibility: The @objc attribute only applies to the class itself, not its subclasses. Therefore, even though your parent class is marked as @objc, its subclass may not be accessible.
  • Visibility: The final keyword in Swift indicates that a class cannot be subclassed. However, this keyword only applies to the class itself, not its subclasses. Therefore, even though your child class is marked as final, it may still be accessible to Objective-C.
  • Compilation: The issue may be caused by a compilation error or a missing dependency. Verify that your Swift class is compiled correctly and that all dependencies are present.

Q: How can I make my child class accessible to Objective-C?

A: To make your child class accessible to Objective-C, you can use the @objc attribute on the child class itself. However, this may not be enough, as the @objc attribute only applies to the class itself, not its subclasses.

Q: What is the difference between @objc and @objc open?

A: The @objc attribute makes a class accessible to Objective-C, while the @objc open attribute makes a class accessible to Objective-C and allows it to be subclassed.

Q: How can I verify that my class is being compiled correctly?

A: You can verify that your class is being compiled correctly by checking the output file generated by the ipsw class-dump command. If your class is not present in the output file, it may indicate a compilation error or a missing dependency.

Q: What are some common mistakes that can cause this issue?

A: Some common mistakes that can cause this issue include:

  • Missing @objc attribute: Failing to use the @objc attribute on the parent class or child class.
  • Incorrect @objc attribute usage: Using the @objc attribute incorrectly, such as using it on a subclass instead of the parent class.
  • Compilation errors: Failing to compile the Swift class correctly or missing dependencies.

Q: How can I troubleshoot this issue?

A: To troubleshoot this issue, you can try the following steps:

  • Verify class visibility: Use the ipsw class-dump command to verify that the class is present in the output file.
  • Check for compilation errors: Verify that the Swift class is compiled correctly and that all dependencies are present.
  • Use the @objc attribute: Use the @objc attribute on the parent class or child class to make it accessible to Objective-C.

Conclusion

In conclusion, the issue of a child class of an @objc class not being found can be caused by a combination of factors, including accessibility, visibility, and compilation. By following the steps outlined in this article, you can troubleshoot and resolve this issue. Remember to verify that your Swift class is compiled correctly and that all dependencies are present.