Skip to content

Fetching Objects from Objection #4

Closed
tziem opened this Issue Aug 17, 2011 · 5 comments

2 participants

@tziem
tziem commented Aug 17, 2011

Hi,

I have following use case:

@protocol IFoo <NSObject>
-(void)doFoo; 
@end

@interface Foo : NSObject <IFoo> {
    Bar* _bar;
}
@property (nonatomic, retain) Bar* bar;
@end

@implementation Foo
objection_register(Foo)
objection_requires(@"bar")

@synthesize bar = _bar;

-(void)doFoo {
}
@end

@interface Bar : NSObject {
}
-(void)doBar;
@end

@implementation Bar
-(void)doBar {
}
@end

[self bind:[[Foo alloc] init] toProtocol:@protocol(IFoo)];

If I'm asking the injector for an implementation of IFoo:

[[JSObjection globalInjector] getObject:@protocol(IFoo)];

then an instance of Bar will not be injected by the injector.
But if I'm asking for a class:

[[JSObjection globalInjector] getObject:[Foo class]];

then Bar will be injected.

Is that the expected behavior?

Thanks,
Thomas Ziem

@dewind
dewind commented Aug 17, 2011

No,

Because you allocated that object manually as apposed to using Objection. In order to do something like that Objection would need to be modified to bind a particular concrete class to a protocol. Protocols are are atypical in Objection and I think under normal circumstances that using the concrete implementation is fine.

However, I can see this being a legitimate use case and I will keep this issue open as a feature request.

@dewind dewind was assigned Aug 17, 2011
@tziem
tziem commented Aug 18, 2011

I found a workaround using a Custom Objection Provider:

@interface FooProvider : NSObject <JSObjectionProvider> { }
@end

@implementation FooProvider
- (id)createInstance:(JSObjectionInjector*)context {
    return [context getObject:[Foo class]];
}
@end

[self bindProvider:[[[FooProvider alloc] init] autorelease] toProtocol:@protocol(IFoo)];

I have also tried to use a block:

[self bindBlock:^(JSObjectionInjector *context) {
    return [context getObject:[Foo class]];
} toProtocol:@protocol(IFoo)];

But this ends with an exception:

NSInvalidArgumentException: reason: -[MyModule bindBlock:toProtocol:]: unrecognized selector sent to instance

This is the first time I'm using blocks.
Any idea?

~Thomas

@dewind
dewind commented Aug 18, 2011

tziem,

There is a preprocessor conditional in Objection that will remove block bindings if you are trying to target iOS 3 OR you built with an SDK that pre-dates the 4.0 SDK.

#if NS_BLOCKS_AVAILABLE
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toClass:(Class)aClass;
- (void)bindBlock:(id (^)(JSObjectionInjector *context))block toProtocol:(Protocol *)aProtocol;
#endif
@tziem
tziem commented Aug 18, 2011

Thanks for the hint, Justin!
I have mistakenly build objection with artifact:ios3.
Now it works!

~Thomas

@dewind
dewind commented Aug 18, 2011

No problem!

@dewind dewind closed this in 2e137cc Aug 19, 2011
@dewind dewind was unassigned by kuleszaj Dec 8, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.