I'm doing an iPhone plugin project where I build a static library, let's call it lib1.a, which I provide to other programmers.
When they link lib1.a into their project, they may also link lib2.a, which they build themselves based on a header file I give them. This header only contains a "hook" function which instantiates an obj-c object.
This all works fine, but I'd like for the project linking lib1.a not to have to link lib2.a. Keep in mind that iOS only supports stati开发者_JAVA技巧c libraries, and I don't want to provide several versions of lib1.a.
Thanks, Chris. I ended up with something similar: the optional lib2.a contains a factory class which creates a an object that implements a certain protocol that exposes the optional functionality. This is the header:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol OptionalStuffDelegate
// Delegate methods here
@end
@protocol OptionalStuff
// Methods here
@end
@interface OptionalStuffFactory : NSObject {}
+ (id<OptionalStuff>)instantiateWithDelegate:(id <OptionalStuffDelegate>)delegate baseView:(UIView *)baseView;
@end
To instantiate in lib1.a, I do:
Class optionalStuffFactoryClass = NSClassFromString(@"OptionalStuffFactory");
if (optionalStuffFactoryClass != nil)
{
optionalStuff = [optionalStuffFactoryClass performSelector: @selector(instantiateWithDelegate:baseView:) withObject: self withObject: glView];
}
lib2.a implements the factory class. The fact that there aren't any compile-time references to the OptionalStuffFactory class makes sure there are no unresolveds if lib2.a is missing.
Important: You have to make sure the build target that includes the library uses the linker flag -ObjC, otherwise the factory class will be optimized away since there are no compile-time references to it.
Can't you, in objective-C, use a static library to add a Category - with new methods, to an existing objective-C class.
So, if lib1.a contains
@interface SomeObjectThatWantsToCallback
Then, lib2.a would contain the definition of
@interface SomeObjectThatWantstoCallBack (CallbackImpl)
-(void)HookProc:{
}
Now, if code in SomeObjectThatWantsToCallBack in lib1.a needs to call the HookProc it can do
if( [self respondsToSelector: @selector( HookProc: )])
[self HookProc];
Well, something like that. Assuming the lib2.a code has been added the category should have extended the class with the method.
If you made the hook register itself, then the presence of the hooking code would self register, the lack thereof, would not. Obviously, only call registered hook functions from lib1.a and you're good to go:-
You don't need to do anything complicated, just use the basic features of c/c++/obj-c to get this kind of behaviour.
精彩评论