atomicobject / objection Goto Github PK
View Code? Open in Web Editor NEWA lightweight dependency injection framework for Objective-C
Home Page: http://www.objection-framework.org
License: MIT License
A lightweight dependency injection framework for Objective-C
Home Page: http://www.objection-framework.org
License: MIT License
it appears Objection is unable to inject a property declared in a category.
@interface WTAppDelegate (PrivateDependencies)
@property (nonatomic, strong) WTNotificationRoutingBehavior *notificationRoutingBehavior;
@end
@implementation WTAppDelegate
objection_requires_sel(@selector(notificationRoutingBehavior))
@end
Is this the intended behavior? Or have I simply stumbled across an edge-case?
Is this something Objection should be capable of? I'm happy to submit a PR if so.
2014-09-24 17:18:45.036 Wingtip[65236:60b] *** Terminating app due to uncaught exception 'JSObjectionException', reason: 'Unable to find property declaration: 'notificationRoutingBehavior' for class 'WTAppDelegate''
*** First throw call stack:
(
0 CoreFoundation 0x00000001047a2495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001044f999e objc_exception_throw + 43
2 Wingtip 0x0000000100dc432d GetProperty + 301
3 Wingtip 0x0000000100dc3c2b -[JSObjectionRuntimePropertyReflector propertyForClass:andProperty:] + 75
4 Wingtip 0x0000000100dbedce +[JSObjection propertyForClass:andProperty:] + 78
5 Wingtip 0x0000000100dc4c9c InjectDependenciesIntoProperties + 588
6 Wingtip 0x0000000100dc11bb -[JSObjectionInjector injectDependencies:] + 123
7 Wingtip 0x0000000100cd92c4 -[WTAppDelegate configureObjection] + 804
8 Wingtip 0x0000000100cd8a89 -[WTAppDelegate application:didFinishLaunchingWithOptions:] + 89
9 UIKit 0x00000001035043d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
10 UIKit 0x0000000103504be1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1605
11 UIKit 0x0000000103508a0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
12 UIKit 0x0000000103519d4c -[UIApplication handleEvent:withNewEvent:] + 3189
13 UIKit 0x000000010351a216 -[UIApplication sendEvent:] + 79
14 UIKit 0x000000010350a086 _UIApplicationHandleEvent + 578
15 GraphicsServices 0x0000000105e6271a _PurpleEventCallback + 762
16 GraphicsServices 0x0000000105e621e1 PurpleEventCallback + 35
17 CoreFoundation 0x0000000104724679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
18 CoreFoundation 0x000000010472444e __CFRunLoopDoSource1 + 478
19 CoreFoundation 0x000000010474d903 __CFRunLoopRun + 1939
20 CoreFoundation 0x000000010474cd83 CFRunLoopRunSpecific + 467
21 UIKit 0x00000001035082e1 -[UIApplication _run] + 609
22 UIKit 0x0000000103509e33 UIApplicationMain + 1010
23 Wingtip 0x0000000100cbcdff main + 351
24 libdyld.dylib 0x0000000104ddf5fd start + 1
I'm using the latest build but it says in the website it only supports 5.0 and higher. However, our project is still supporting 4.3 and it still works.
Are there any specific case where it'll cause a problem with 4.x?
The JS prefix on classnames causes cognitive dissonance, and it feels to me like Objection is already enough of a qualifier.
Eg, ObjectionInjector is more harmonious when held in mental-space than JSObjectionInjector.
Sometimes you might want to wire up two instances of the same Protocol (or Class). They might be the same implementation with different configuration, or they might be different implementations.
For example, you might have a protocol that fetches movie titles. One instance might point to a database that has "Comedy" and another that has "Action". Or they might point to different servers.
Then you could bind them in a module like this:
[self bind:comedy toProtocol:@protocol(MovieSource) withQualifier:@"comedy"];
[self bind:action toProtocol:@protocol(MovieSource) withQualifier:@"action"];
There could be additional register macros that take NSString qualifiers too.
Then manually get them like this:
id comedy = [injector getObject:@protocol(MovieSource) withQualifier:@"comedy"];
Not sure what the additional requires macros would look like.
Hi,
Firstly thanks for this library. I am finding it really useful.
I just wanted to request a method for unregistering a class:
Currently when you need to create objects that have dependencies you need to set and then get the global instance. ie, somewhere in my class i need to create another object...
- (void)someMethod {
// first get the global instance
JSObjectionInjector *injector = [JSObjection globalInjector];
// then use the injector to create something.
// NB: this is NOT a dependency
}
This reduces the injector to little more than a service locater. I think it would be more useful, and more testable, to allow the injector to itself be injected as a dependency. So if your class needs to create other objects you simply ask for the injector as one of your dependencies.
@interface MyClass
@property (nonatomic, retain) JSObjectionInjector *injector;
@end
@implementation MyClass
objection_register( MyClass );
objection_requires( @"injector" );
I am currently doing this through my own "Injector Provider", but I think it would be a good feature to have built in.
It would be very useful to have the option of marking requirements as optional. At the moment if a dependency is not satisfied Objection throws an exception, however it should be able to check whether the dependency was optional or not and suppress the exception if it was.
I have the following initialiser in a class:
objection_initializer(initWithComms:)
-(instancetype) initWithComms:(Comms *) commsX {
self = [super init];
if (self) {
_comms = commsX;
}
return self;
}
However when I run the code the commsX argument is nil. I've tried to follow the Objection code and it appears that it is building an instance of the Comms object and putting it into it's context. However it's not passed through to the code that actually creates the instance of this code.
Am I doing anything wrong? I found the sample code on the Objection website rather difficult to follow :-(
I seem to be having a problem with dependency injection configuration. Actually there are two things that I am struggling with.
The first issue is that from the Objection website it seems that the only thing I need to do is add a property for my dependencies ex:
@property (nonatomic, weak) id<someModelService> someModelService
and add the clause:
objection_requies_sel(@selector(someModelService))
But It didn't seem to work until I added in the init function:
[[JSObjection defaultInjector] injectDependencies:self];
This is of course given the fact that I have added
[self bind:[ModelServiceImpl new] toProtocol:@protocol(someModelService)];
in the JSObjectionModule subclass that I have set as the default injector.
The second issue could be related to something I'm missing that is causing the first issue but here it goes:
In my DependencyModule subclass I have the following two lines:
[self bind:[ModelDaoImpl new] toProtocol:@protocol(someModelDao)];
[self bind:[ModelServiceImpl new] toProtocol:@protocol(someModelService)]; //Is dependent on someModelDao protocol and adds it as a dependency
But since the second object is dependent on the first one, if I call:
[[JSObjection defaultInjector] injectDependencies:self];
nothing will happen and someModelDao won't be injected because defaultInjector
is not setup yet.
I have been looking for tutorials or examples but I can't come across any?
There's mention in http://spin.atomicobject.com/2012/02/13/objection-is-over-1-year-old/
about an example proj in the repo, but the project that I found is just the source code and tests.
Thanks for such an awesome project.
It would be interesting if a module could add an NSDictionary to an injector and have a new macro that maps keys in that dictionary to properties.
Something like:
@interface MyModule : JSObjectionModule
@end
@implementation MyModule
-(void) configure
{
[self bindNames:@{@"NamedProperty" : @"This will be a named Property"}];
}
@end
@interface MyObject
@property (weak, nonatomic) NSString* myProperty;
@end
@implementation
objection_requires_names(@{@"NamedProperty" : @"myProperty"})
@end
While not needed it would be nice to have a convience method that would load a plist like that.
When try to recreate a new injector and set it as new default injector, the old injector won't be deallocated. Once I changed the reference type of property injector from strong to weak/assign in class JSObjectFactory, it fixed dealloc issue. Is it a bug? Or it is supposed to work like that?
Cheers
Our crashlogger is reporting these exceptions and we are getting a lot. Problem is our crash log is not properly symbolicated so we don't really know where to look aside from looking for code with the property name:
reason = Unable to find property declaration: 'dhUiController';
stackTrace =
(
0 CoreFoundation 0x3528f3ff + 186
1 libobjc.A.dylib 0x36209963 objc_exception_throw + 30
2 DreamHouse 0x002a0dfd DreamHouse + 2280957
3 DreamHouse 0x0029f84d DreamHouse + 2275405
4 DreamHouse 0x0029f60d DreamHouse + 2274829
5 DreamHouse 0x0029ff63 DreamHouse + 2277219
6 DreamHouse 0x00183203 DreamHouse + 1110531
7 DreamHouse 0x00204061 DreamHouse + 1638497
8 DreamHouse 0x00205d17 DreamHouse + 1645847
9 DreamHouse 0x00227959 DreamHouse + 1784153
10 UIKit 0x33b05441 + 5680
11 CoreFoundation 0x35264941 + 20
12 CoreFoundation 0x35262c39 + 276
13 CoreFoundation 0x35262f93 + 746
14 CoreFoundation 0x351d623d CFRunLoopRunSpecific + 356
15 CoreFoundation 0x351d60c9 CFRunLoopRunInMode + 104
16 GraphicsServices 0x36a8533b GSEventRunModal + 74
17 UIKit 0x33b50291 UIApplicationMain + 1120
18 DreamHouse 0x000bc06f DreamHouse + 295023
19 DreamHouse 0x00076058 DreamHouse + 8280
);"""
Question is when exactly is this exception raised? We're sure that we have the correct name cause it'll crash right away if it doesn't. Another problem is we haven't experienced the crash ourselves (during testing), it only shows up on our crash logs.
It took me a while to figure out how to integrate Objection well with Kiwi specs. I ended up building something to make this process simpler: https://github.com/mindsnacks/MSSpec
I figured I'd share this here, and maybe it will serve as inspiration to either document or reference this project in the README :)
Looks like setGlobalInjector and globalInjector have been renamed to setDefaultInjector/defaultInjector. Is there any way the main page doc can reflect that change?
I've added a failing spec that illustrates this issue on a branch resolve_all_deps_before_notifying_singletons.
Sounds like a couple hour task. If there a complication supporting OSX (I'm only familiar with iOS)? If not I'd gladly submit a PR.
My unit test currently calls a class called ABTestConfig which creates an injector using a Module and assigns this to the defaultInjector. I have followed this happening in the debugger and can see the value assigned to gGlobalInjector.
When the method in the unit test is run e.g. testExample then this calls another method that tries to get the defaultInjector from JSObjection and I get a nil back. Using the debugger I have confirmed that the value of gGlobalInjector is indeed nil.
Any idea why this is happening?
Is Objection incompatible with unit testing as that would be a real shame!
I will provide code examples if needed.
There are some situations where the creation of an object is inaccessible because of framework architecture, for example the creation of UIStoryboard occurs in a static/class method. Subclassing it won't help as ultimately we have no access to what happens in that method and can't replicate the creation in an overridden method without risking bypassing crucial setup code. There are plenty of other instances where we would still want to use injection, but can't rely on the injector creating the object.
For this reason it would be hugely useful to be able to pass an object to Objection and ask for injection to occur into the already created object. This functionality already exists in JSObjectionInjectorEntry::buildObject, though it is currently obscured from usage.
Essentially I am asking for something like:
JSObjectionInjector::injectIntoObject:(id)object
I have an object called "MCEntry" that needs a field on it called "NSFNanoStore". I'd like to treat the NSFNanoStore as a singleton, but I'm a bit stymied at how to do this. I've set up my project like the following
@implementation AppModule {}
- (void)configure {
[self bindBlock:^(JSObjectionInjector *context){
NSFNanoStore *store = [NSFNanoStore createAndOpenStoreWithType:NSFPersistentStoreType path:[self pathForNanoStore] error:nil];
return (id)store;
} toClass:[NSFNanoStore class]];
}
@end
@implementation MCEntry {
}
objection_register(MCEntry)
objection_requires(@"nanoStore")
@synthesize bodyFat;
@synthesize muscle;
@synthesize weight;
@synthesize nanoStore;
@synthesize dateString;
...
@end
But when I try to create an instance of MCEntry using the injector, the nanoStore field of the MCEntry instance is nil:
savedEntry = [[JSObjection defaultInjector] getObject:[MCEntry class]];
Am I doing this incorrectly?
Please consider publishing API docs, that can be linked to.
Happy to contribute a nice looking Doxygen config file, etc.
The impression I get after reading http://objection-framework.org/ is that the import statement necessary for an iOS application is something like
#import <Objection-iOS/Objection.h>
yet this is not the case if you use a Podfile
to manage library dependencies.
For the sake of consistency please add an Include Framework
section for the Cocoapods section.
Hi,
when I'm using the JSObjectionProvider protocol or a block to manually construct an object I always get a new instance even if I declare it as singleton.
~Thomas
Currently the library does not detect circular dependencies which means that the library will go into infinite recursion until it encounters a stack overflow error. At the very least we should detect circular dependencies and throw an exception.
I've got the same problem as it was mentioned here: #50
Because no one have answered my question from comment to that issue, I'm creating new one.
How should I use Objection and cocoapods to the same defaultInjector in tests and main target?
suppose I have a ViewController
which can init in multi ways like -initWithCategory:
, -initWithTag:
, etc. how to deal this scenario? cause objection_initializer
seems can be used once.
use one init
and multi -configureWithCategory:
, -configureWithTag:
?
The new programming language Swift is awesome but unfortunately it doesn't seem to support things like defines.
So we would need an other approach to define the dependencies of our classes without maintaining a lots of factories/providers.
Any ideas yet?
Maybe it was just my reading, but from going over the documentation I thought each class had to be bound in a module before use.
In addition all of the examples of registering a module uses alloc/init on the bind so any injections of those instances won't be injected. These two led me to think there was a problem with nested injections until I realized what was going on.
I have just started using Objection in a Mac OS X project. I'm finding a problem when trying to inject a dependency that implements a protocol.
I have a LoginService class that implements the protocol ILoginService. I keep an object that implements ILoginService inside another class named SessionManager. Now I register LoginService class with ILoginService using a Module in Objection. However, when trying to automatically inject the property that implements ILoginService in SessionManager I get the following error.
"Cannot find an instance that is bound to the protocol 'ILoginService' to assign to the property 'loginService'"
My code looks like follows.
========== start of code ==============================
@protocol ILoginService
@interface LoginService : NSObject
{
}
@implementation LoginService
// implementation code
@protocol ISessionManager
@interface SessionManager : NSObject
{
id loginService;
}
@Property(strong) id loginService;
@implementation SessionManager
objection_register_singleton(SessionManager)
objection_requires(@"loginService")
@synthesize loginService;
// implementation code
@interface MyInjectorModule : JSObjectionModule
@implementation MyInjectorModule
// inside Application main method
JSObjectionInjector *injector = [JSObjection createInjector:[[MyInjectorModule alloc] init]];
[JSObjection setDefaultInjector:injector];
id sessionManager = [[JSObjection defaultInjector] getObject:@protocol(ISessionManager)]; // I get the above mentioned error when executing this line
========= end of code ================================
If I rather use the concrete class name in the LoginManager property declaration in SessionManager (i.e. LoginService *loginService) it works. However I need to keep the loginService property with the type id so that the concrete class can be changed in the future.
Is there a way to achieve this in Objection?
Hi guys,
Maybe this is not the correct place but I couldn't find anywhere else so here we go.
I just executed pod outdated
and saw that version 1.3.1 of objection was available and I'm on 1.2.1 so I was looking for a What's New/Changelog and couldn't find it. It would be really nice to have one.
when using Objection within Objective-C++ code we are getting these errors:
In file included from .../SomeFile.mm:10:
In file included from .../Objection/Objection.h:11:
.../Objection/JSObjectionUtils.h:4:17: error: default initialization of an object of const type 'NSString *const __strong'
NSString *const JSObjectionInitializerKey;
^
.../Objection/JSObjectionUtils.h:5:17: error: default initialization of an object of const type 'NSString *const __strong'
NSString *const JSObjectionDefaultArgumentsKey;
^
2 errors generated.
Unless I am missing something there is currently no way to bind a class to another class.
This would allow a parameter typed to an Abstract superclass to be satisfied by a Concrete subclass.
The method signature would look like this:
Expected result: object binded to protocol initialized with argument passed on step 3.
Actual result: object initialized with argument specified on step 1 with no respect to values passed on step 3.
There is a way to add / change bindings on live injector? Or create new injector with old and additional context?
I have to refactor some of my code, and now database classes are dependent on username.
All across the code i use id and id protocols, and now i need to change this binding at program runtime? There is a way to do this?
Is there a chance to get a fully working example, to see when and how to use objection in a more application stile example. E.g. is it useful to use objection for every kind of objects (view, controller, object)?
Regards
We have a scenario where we want to derive a new injector from an existing one with additional modules when displaying a new view controller. The existing injector has singleton instances that are already cached within it, and we need to use the same instance of them in the new injector.
Currently, using withModuleOfType:
will create a new injector with the same global context, but with new injection entries that will create new instances of the singletons upon request.
It makes sense to me that derives injectors will produce the same singletons of the original injector, since we want to inherit the behavior of the original injector, including its context. What do you think?
Additionally, if anyone got any idea on how to overcome this in a different, elegant way, I'd be happy to know.
The example code snippets have it, like:
(1)
@interface CarProvider : NSObject <JSObjectionProvider>
@end
@implementation CarProvider
(2)
- (id)provide:(JSObjectionInjector *)context arguments:(NSArray *)arguments {
// Manually build object
return car;
}
@end
Two things need to be updated on the README and on the main page:
@interface
declarationprovide:arguments:
Please update the documentation!
A module shouldn't be the only way an object can be injected into the injector context outside of the default registration mechanism.
I'm unable to archive my app if I add Objection it includes my app includes an armv6 architecture. How could I get this to work against armv6?
Error is as follows:
ld: in /Users/ncurran/workspace/main/Libraries/Objection-iOS.framework/Objection-iOS, file is universal but does not contain a(n) armv6 slice for architecture armv6
Currently if I want the injector to supply a singleton to one of my classes I have the following options:
Which registers a class to be created when first asked for and shared as a singleton.
Which registers a class to be created immediately and shared as a singleton.
But I have no way of having a singleton mapped to a protocol. No way to say; 'Whenever asked for a dependency of SomeProtocol satisfy it with a (singleton) instance of SomeClass.
Hello dewind, thank you for fantastic work. This is my first foray into DI so I apologize if this is a silly question.
I'm trying to understand how to inject custom-created objects with Objection. My current understanding is that an JSObjectionInjector requires a JSObjectionModule to map classes to instance. So to use the defaultInjector I need to instantiate a subclass of JSObjectionModule. The recommended approach is to create defaultinjector in application:didFinishLaunching:. The problem with this is that my JSObjectionModule subclass doesn't know how to construct my custom object yet, it is in fact dependent on some further user actions.
How would you recommend I proceed in this case?
Xcode 4.3 installs under /Applications
and CLI tools live in /usr/bin
instead of /Developer/usr/bin
. Building fails because xcodebuild
is expected to still be under /Developer
. Changing to new location works for me:
def xcodebuild_executable
"/usr/bin/xcodebuild"
end
But my Ruby-fu isn't strong enough to know the best way to make this conditional so it works for Xcode 4.2 and before, otherwise I'd send a pull request.
I'm getting an exception thrown when trying to register an eager singleton which I'm registering/binding within a module, like so:
@implementation MyAppModule
- (void)configure {
[self bindClass:[Foo class] inScope:JSObjectionScopeSingleton];
[self registerEagerSingleton:[Foo class]];
}
@end
This throws an exception in -[JSObjectionInjector initializeEagerSingletons] because there isn't a binding in the global context.
Would you be agreeable to a pull request that changes -initializeEagerSingletons to check for an entry in _context as well?
So, I'm getting an EXEC_BAD_ACCESS
on this situation: AuthenticationService
-> SingletonHttpClient
-> AuthenticationService
(-> denotes requires)
@implementation AuthenticationService
objection_requires_sel(@selector(singletonHttpClient))
@end
@implementation SingletonHttpClient
objection_register_singleton(TTTophatService)
objection_requires_sel(@selector(authenticationService)) // EXEC_BAD_ACCESS here
@end
Do you think it is possible to Objection to support this kind of dependency?
FYI if I register AuthenticationService
as singleton the crash stops but the AuthenticationService
.singletonHttpClient
instance does not match the singleton instance that everybody else gets. Besides the fact that it shouldn't be singleton so not a real solution.
This is to support testing. It would be nice to be able to specify that a particular class registered with Objection is the preferred one to be instantiated. For example, when testing, I could specify a test class (or mock of some sort) will be returned by Objection instead of the one from the app.
The Spring framework has this concept (for Java) and I've found it very useful for providing stubbed out classes for predictable testing scenarios.
Thanks
For many iOS developers DI is most useful if all of the ViewControllers' dependencies can be injected. However, when an iOS project uses Storyboards, the system instantiates the ViewController for you.
This instance of a ViewController is unknown to Objection, which is problematic because it may need to listen out for delegate methods of various other components of the system.
The ideal way is to hijack the ViewController's instantiation code and have all dependencies beneath ViewController be resolved by Objection, maximising this project's utility and convenience for the programmer.
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
Hi folks, I ran across a case where Objection doesn't give me the control I need during testing. I'm curious if anyone else has seen the same issue and if I can propose an appropriate solution in line with the design of the rest of the framework.
I'm writing integration/functional tests where I deliberately exercise many classes, several of which have been instantiated via Objection. Some of these classes are registered with Objection as singletons (via objection_register_singleton()
) and as such multiple other classes might have been given references to the same instance.
These singletons introduce our old enemy global mutable state. I want to make sure that state is reset between test cases so that the order in which tests are run cannot influence their outcome (for example a queue of pending network requests might need to be emptied between tests).
As is I might manually reset these states but that requires that my test be aware of, able to access, and coupled to all of these dependencies. I would rather not tightly couple my test of a high level interface to implementation details of classes deep in the object graph the test produces.
Alternately I see [JSObjection reset]
which clears the global context. Unfortunately this destroys the JSObjectionInjectorEntry
s in that context and the scope with which they were registered as well. Since objection_register_singleton
implements +initialize
I can't easily re-run those registration calls. As a result classes which were once singletons no longer are.
I considered creating a new JSObjectionInjector
instance without the same global context but allowing an injector's global context to not match JSObjection
's gObjectionContext
seems like a violation of Objection's expected behavior. In addition there's no public mechanism to obtain a JSObjectionInjector
's set of modules so I cannot currently init a new injector with the same module set but an empty context.
I can obviously reach into Objection's internals to make this work for now but is there an appropriate public interface we could expose to solve this problem?
What is the intended use of [JSObjection reset]
? Is it important that it clear the scope with which classes are registered? Is so does it seem appropriate to introduce a new method which discards the _storageCache
from each JSObjectionInjectorEntry
in the JSObjection
gObjectionContext
?
As an example I'd like to be able to write something like:
@interface TestObserver : XCTestObserver
@end
@implementation TestObserver
- (void)testCaseDidStart:(XCTestRun *)testRun {
[JSObjection resetSingletons];
[super testCaseDidStart:testRun];
}
@end
I am trying to use Objection to mock out a few components in my OCUnit tests, but I'm running into a problem where [JSObjection defaultInjector]
returns a different value in the tests than the app.
In my app, I have:
[JSObjection setDefaultInjector:[JSObjection createInjector]];
NSLog(@"Main binary injector: %p", [JSObjection defaultInjector]);
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"Main binary injector after change: %p", [JSObjection defaultInjector]);
});
And in my test I have:
NSLog(@"ocunit initial injector: %p", [JSObjection defaultInjector]);
[JSObjection setDefaultInjector:[JSObjection createInjector]];
NSLog(@"ocunit injector: %p", [JSObjection defaultInjector]);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, NO);
The flow is basically, that the app sets the default injector and the tests then reads it. After that, the test changes the default injector and the then app reads it.
I would expect the output to be two matching pointers, followed by two different matching pointers. What I get is:
2013-08-14 23:05:22.939 ObjectionDefect[96881:c07] Main binary injector: 0xe793850 2013-08-14 23:05:23.045 ObjectionDefect[96881:c07] ocunit initial injector: 0x0 2013-08-14 23:05:23.045 ObjectionDefect[96881:c07] ocunit injector: 0x7491230 2013-08-14 23:05:24.940 ObjectionDefect[96881:c07] Main binary injector after change: 0xe793850
A little probing reveals that &gGlobalInjector
is different for the two binaries.
I am using Objection 1.0.3 via CocoaPods. I had used a previous version as a subproject in the past without issue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.