johnno1962 / HotReloading

Hot reloading as a Swift Package

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Could not work for ObjC: Number of class refs 1 does not equal []

tinymind opened this issue · comments

Hi, I tried SwiftUI-Kit on device, it works fine.
But when I tested on my Objective C project, it was failed.

Here is the output:

🔥 Compiling Demo/HotReloadingDemo/HotReloadingDemo/ViewController.m
🔥 ⚠️ Number of class refs 1 does not equal []
🔥 ⚠️ Could not locate descriptors section

The demo project is very simple, only one core file ViewController.m, and here is the source:

// ViewController.m

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (IBAction)onTestButtonClicked:(id)sender {
    self.view.backgroundColor = [UIColor greenColor]; // Change the color type then `Command + S`
}

@end

Thanks for your time.

PS: the same code works well on simulator.

Hi, I'm afraid Objective-C and on-device injection is a bad combination due to insufficient information being provided by the compiler to simulate dynamic loading.

Oops, that is a bad news.

It's not all bad news, there are just arbitrary things you need to avoid, for example if you remove the message to super in viewDidLoad in the example you should find it works.

Em, I removed [super viewDidLoad]; but it not works, same error happened.
Even if it could work by remove the message to super, it's not a perfect resolution cause usually we need to call super indeed.

Injection on device is currently not "a perfect solution". The error you're seeing is Injection complaining about missing Swift specific information not provided by Objective-C in the object file. My criteria for "working" is updating and not crashing. It works quite well for prototyping SwiftUI but aside from that no guarantees.

Is it possible to fix the problem in other way, like Runtime? Method swizzle instead of re-compile.

Not really without replicating some fairly complex code from inside the dynamic linker (for which the source is available). The current state is pretty much a "best effort" that works better than I expected as Swift seldom depends on pointers in memory initialised with the value of external symbols. Swift generally does everything through "accessors" which are functions I can use a slightly modified version of "fishhook" to "bind".

Got it, thanks for your patience.