Skip to content

Commit

Permalink
Invocation return value ARC bug fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
alexgarbarev committed Jan 29, 2014
1 parent f32c6c1 commit a56e295
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 59 deletions.
6 changes: 3 additions & 3 deletions A-Typhoon.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -758,12 +758,12 @@
BA798CB709B2750980CFFC62 /* TyphoonComponentFactory+InstanceBuilder.h */,
BA798518E11F23A1021A6528 /* TyphoonComponentFactory+InstanceBuilder.m */,
BA79899ED482BE5A9D176ED6 /* TyphoonComponentFactory+TyphoonDefinitionRegisterer.h */,
BA79897F17DB88BEA7549100 /* TyphoonCallStack.m */,
BA798FC918C219BF4F199085 /* TyphoonCallStack.h */,
BA7981BE9FC036F9CB30E1F9 /* TyphoonStackElement.m */,
BA79897F17DB88BEA7549100 /* TyphoonCallStack.m */,
BA798AA10B9FA9B3D53146C0 /* TyphoonStackElement.h */,
BA798E9C35F725B504C22F74 /* TyphoonParentReferenceHydratingPostProcessor.m */,
BA7981BE9FC036F9CB30E1F9 /* TyphoonStackElement.m */,
BA7988CB0A04D544852FC120 /* TyphoonParentReferenceHydratingPostProcessor.h */,
BA798E9C35F725B504C22F74 /* TyphoonParentReferenceHydratingPostProcessor.m */,
);
path = Internal;
sourceTree = "<group>";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
*/
@interface TyphoonComponentFactory (InstanceBuilder)

- (id)newInstanceWithDefinition:(TyphoonDefinition*)definition;
- (id)buildInstanceWithDefinition:(TyphoonDefinition*)definition NS_RETURNS_RETAINED;

- (id)newSharedInstanceForDefinition:(TyphoonDefinition*)definition;
- (id)buildSharedInstanceForDefinition:(TyphoonDefinition*)definition NS_RETURNS_RETAINED;

- (void)injectPropertyDependenciesOn:(__autoreleasing id)instance withDefinition:(TyphoonDefinition*)definition;

Expand Down
44 changes: 20 additions & 24 deletions Source/Factory/Internal/TyphoonComponentFactory+InstanceBuilder.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
#import "TyphoonStackElement.h"
#import "NSObject+PropertyInjection.h"

#import <objc/runtime.h>

#define AssertTypeDescriptionForPropertyOnInstance(type, property, instance) if (!type)[NSException raise:@"NSUnknownKeyException" \
format:@"Tried to inject property '%@' on object of type '%@', but the instance has no setter for this property.",property.name, [instance class]]

Expand All @@ -53,23 +55,20 @@ @implementation TyphoonComponentFactory (InstanceBuilder)
/* ====================================================================================================================================== */
#pragma mark - Initialization & Destruction

- (id)newInstanceWithDefinition:(TyphoonDefinition*)definition
- (id) buildInstanceWithDefinition:(TyphoonDefinition*)definition
{
id <TyphoonIntrospectiveNSObject> instance = nil;

instance = [self newInitializedInstanceWithDefinition:definition];
id <TyphoonIntrospectiveNSObject> instance = [self newInstanceWithDefinition:definition];
[_stack push:[TyphoonStackElement itemWithKey:definition.key instance:instance]];
[self injectPropertyDependenciesOn:instance withDefinition:definition];
[_stack pop];

instance = [self postProcessInstance:instance];
[_stack pop];

return instance;
}

- (id) newInitializedInstanceWithDefinition:(TyphoonDefinition*)definition NS_RETURNS_RETAINED
- (id) newInstanceWithDefinition:(TyphoonDefinition*)definition
{
id instance = nil;
id instance = nil;

if (definition.factoryReference)
{
Expand All @@ -79,23 +78,20 @@ - (id) newInitializedInstanceWithDefinition:(TyphoonDefinition*)definition NS_RE
}
else
{
/* Sending init later after alloc is wrong, see http://www.foldr.org/~michaelw/objective-c/ObjectiveC/5RunTime/Allocation__tialization.html
* It is reason to refactor */
/* Sending init later after alloc is dangerous and was reason of few bugs,
* It was a reason to refactor */

id target = definition.initializer.isClassMethod ? definition.type : [definition.type alloc];

void *initializedObjectPointer = NULL;

NSInvocation *invocation = [self invocationToInitDefinition:definition];

if (definition.initializer && definition.initializer.isClassMethod) {
[invocation setTarget:definition.type];
} else {
[invocation setTarget:[definition.type alloc]];
}
[invocation invokeWithTarget:target];
[invocation getReturnValue:&initializedObjectPointer];

[invocation invoke];
[invocation getReturnValue:&instance];
instance = (__bridge id) initializedObjectPointer;
}



[self handleSpecialCaseForNSManagedObjectModel:instance];

return instance;
Expand Down Expand Up @@ -162,13 +158,13 @@ - (void)injectAssemblyOnInstance:(id <TyphoonComponentFactoryAware>)instance;
[instance setFactory:self];
}

- (id)newSharedInstanceForDefinition:(TyphoonDefinition*)definition
- (id)buildSharedInstanceForDefinition:(TyphoonDefinition*)definition
{
if ([self alreadyResolvingKey:definition.key])
{
return [_stack peekForKey:definition.key].instance;
}
return [self newInstanceWithDefinition:definition];
return [self buildInstanceWithDefinition:definition];
}


Expand All @@ -180,7 +176,7 @@ - (BOOL)alreadyResolvingKey:(NSString*)key
/* ====================================================================================================================================== */
#pragma mark - Property Injection

- (void)injectPropertyDependenciesOn:(id)instance withDefinition:(TyphoonDefinition*)definition
- (void)injectPropertyDependenciesOn:(__autoreleasing id)instance withDefinition:(TyphoonDefinition*)definition
{
[self doBeforePropertyInjectionOn:instance withDefinition:definition];

Expand Down Expand Up @@ -289,7 +285,7 @@ - (BOOL)propertyIsCircular:(TyphoonAbstractInjectedProperty*)property onInstance
return [[instance circularDependentProperties] objectForKey:property.name] != nil;
}

- (void)injectCircularDependenciesOn:(id <TyphoonIntrospectiveNSObject>)instance
- (void)injectCircularDependenciesOn:(__autoreleasing id <TyphoonIntrospectiveNSObject>)instance
{
NSMutableDictionary* circularDependentProperties = [instance circularDependentProperties];
for (NSString* propertyName in [circularDependentProperties allKeys])
Expand Down
28 changes: 6 additions & 22 deletions Source/Factory/TyphoonComponentFactory.m
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ - (void)instantiateEagerSingletons
}];
}

- (id)instanceForDefinition:(TyphoonDefinition*)definition fromPool:(id<TyphoonComponentsPool>)pool buildBlock:(TyphoonInstanceBuildBlock)buildBlock NS_RETURNS_RETAINED
- (id)instanceForDefinition:(TyphoonDefinition*)definition fromPool:(id<TyphoonComponentsPool>)pool buildBlock:(TyphoonInstanceBuildBlock)buildBlock
{
NSParameterAssert(buildBlock);
@synchronized (self)
Expand All @@ -288,39 +288,23 @@ - (id)instanceForDefinition:(TyphoonDefinition*)definition fromPool:(id<TyphoonC
if (instance == nil)
{
instance = buildBlock(definition);
NSLog(@"1. instance = <%@>",instance);
[pool setObject:instance forKey:definition.key];
NSLog(@"2. instance = <%@>",instance);
}
NSLog(@"3. instance = <%@>",instance);
return instance;
}
}

- (id) sharedObjectGraphInstanceForDefinition:(TyphoonDefinition*)definition fromPool:(id<TyphoonComponentsPool>)pool NS_RETURNS_RETAINED
{
@synchronized (self)
{
id instance = [pool objectForKey:definition.key];
if (instance == nil)
{
@autoreleasepool {
instance = [self newSharedInstanceForDefinition:definition];
}

NSLog(@"1. instance = <%@> (%d)",instance, (int)[instance performSelector:NSSelectorFromString(@"retainCount")]);
[pool setObject:instance forKey:definition.key];
NSLog(@"2. instance = <%@> (%d)",instance, (int)[instance performSelector:NSSelectorFromString(@"retainCount")]);
}
NSLog(@"3. instance = <%@> (%d)",instance, (int)[instance performSelector:NSSelectorFromString(@"retainCount")]);
return instance;
}
return [self instanceForDefinition:definition fromPool:pool buildBlock:^id(TyphoonDefinition *definition) {
return [self buildSharedInstanceForDefinition:definition];
}];
}

- (id) sharedInstanceForDefinition:(TyphoonDefinition*)definition fromPool:(id<TyphoonComponentsPool>)pool NS_RETURNS_RETAINED
{
return [self instanceForDefinition:definition fromPool:pool buildBlock:^id(TyphoonDefinition *definition) {
return [self newInstanceWithDefinition:definition];
return [self buildInstanceWithDefinition:definition];
}];
}

Expand Down Expand Up @@ -362,7 +346,7 @@ - (id)objectForDefinition:(TyphoonDefinition*)definition
break;
default:
case TyphoonScopePrototype:
instance = [self newInstanceWithDefinition:definition];
instance = [self buildInstanceWithDefinition:definition];
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ - (void)test_injects_required_initializer_dependencies
TyphoonDefinition* questDefinition = [[TyphoonDefinition alloc] initWithClass:[CampaignQuest class] key:@"quest"];
[_componentFactory register:questDefinition];

Knight* knight = [_componentFactory newInstanceWithDefinition:knightDefinition];
Knight* knight = [_componentFactory buildInstanceWithDefinition:knightDefinition];
assertThat(knight, notNilValue());
assertThat(knight.quest, notNilValue());
}
Expand All @@ -59,7 +59,7 @@ - (void)test_injects_required_initializer_dependencies_with_factory_method
[urlDefinition setInitializer:initializer];
[_componentFactory register:urlDefinition];

NSURL* url = [_componentFactory newInstanceWithDefinition:urlDefinition];
NSURL* url = [_componentFactory buildInstanceWithDefinition:urlDefinition];
assertThat(url, notNilValue());
}

Expand Down Expand Up @@ -196,7 +196,7 @@ - (void)test_injects_required_property_dependencies
TyphoonDefinition* questDefinition = [[TyphoonDefinition alloc] initWithClass:[CampaignQuest class] key:@"quest"];
[_componentFactory register:questDefinition];

Knight* knight = [_componentFactory newInstanceWithDefinition:knightDefinition];
Knight* knight = [_componentFactory buildInstanceWithDefinition:knightDefinition];
assertThat(knight, notNilValue());
assertThat(knight.quest, notNilValue());
}
Expand All @@ -212,7 +212,7 @@ - (void)test_raises_exception_if_property_setter_does_not_exist

@try
{
Knight* knight = [_componentFactory newInstanceWithDefinition:knightDefinition];
Knight* knight = [_componentFactory buildInstanceWithDefinition:knightDefinition];
STFail(@"Should have thrown exception");
knight = nil;
}
Expand Down
40 changes: 36 additions & 4 deletions Tests/Tests.xcodeproj/xcshareddata/xcschemes/iOS Tests.xcscheme
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
version = "1.3">
<BuildAction>
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForTesting = "YES">
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4B84146B179B0E3900916BF5"
Expand All @@ -17,9 +22,13 @@
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
<TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4B84146B179B0E3900916BF5"
Expand All @@ -31,6 +40,29 @@
</Testables>
</TestAction>
<LaunchAction
useCustomWorkingDirectory = "NO">
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

0 comments on commit a56e295

Please sign in to comment.