Reputation: 10221
Is it possible to weak link my own objective-c classes?
I have seen that I can weak link a function or a variable…
extern int MyFunction() __attribute__((weak_import));
extern int MyVariable __attribute__((weak_import));
I would like to have something like this…
if ([MyUploadManager class]) {
self.uploadButton.hidden = NO;
}
… and be able to compile even if UploadManager.m is not included in the project.
Upvotes: 8
Views: 2317
Reputation: 4497
To weak link a class e.g. MyUploadManager
in your own executable:
To keep the linker happy, add this to Other Linker Flags
in the project:
-Wl,-U,_OBJC_CLASS_$_MyUploadManager
This allows the class symbol to be undefined even if it is not built into your executable. It will be considered for dynamic lookup instead, effectively the same as a dynamic library symbol.
To keep the runtime happy, add this to your class header:
__attribute__((weak_import)) @interface MyUploadManager
When the dynamic linker runs, it substitutes a nil
for the class symbol rather than crashing.
Now you can run this without either linker or runtime errors:
if ([MyUploadManager class]) {
self.uploadButton.hidden = NO;
}
Note: As of Xcode 7, the -U
linker options conflicts with BitCode, so you may not be able to use this technique for future projects.
Upvotes: 9
Reputation: 10221
To weak link a class it can be included in a framework. The compiler can be told to weak link all symbols in a framework using the Other Linker Flag
build setting.
-weak_framework <framework_name>
This enables MyModule.framework to weak link against Uploader.framework whilst it is being built. If someone using MyModule.framework does not links against Uploader.framework then, in the example above, the button will not be displayed.
Upvotes: 1
Reputation: 410762
You can use the NSClassFromString
function:
Class MyUploadManager = NSClassFromString(@"MyUploadManager");
if (MyUploadManager) {
self.uploadButton.hidden = NO;
}
NSClassFromString
returns nil
if the class cannot be found.
Upvotes: 4