Skip to content

Take advantage of weak linking #29

@kirb

Description

@kirb

%c() has shortcomings — for instance the compiler has no idea what type it actually is and can’t do type checking on instancetype methods, forcing use of casts like this:

[(SpringBoard *)[%c(SpringBoard) sharedApplication] doThing];
((SpringBoard *)[%c(SpringBoard) sharedApplication]).isThingDone; // even worse!

Clang supports a weak_import attribute on classes that allows us to skip the linker trying to find the symbol to link, and allows the symbol to be optional just as %c() is.

Which would allow much more elegant code, like maybe:

%weakclass SpringBoard;

//

[[SpringBoard sharedApplication] doThing];
[SpringBoard sharedApplication].isThingDone;

%weakclass X would expand to:

__attribute__((weak_import))
@interface SpringBoard ()
@end

Of course these weak symbols will be resolved at process launch time/library load time just like every other symbol dyld needs to resolve, so %c() is still necessary for late-loaded symbols.

To discuss:

Does this work on a category interface? Worst case scenario, we generate a separate file containing flags to pass the linker for weak import, or use this:

asm(".weak_reference _OBJC_CLASS_$_SpringBoard");

According to this thread the attribute method may require a linker flag anyway due to a limitation of the implementation. I’m really hoping this is a bug and that it’s fixed now, so we can use an #if directive to check the clang version and #error out if it’s a known broken version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestneeds discussionTheos team needs to discuss a solution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions