From 6c771c40b7705dd36e37d941c078298854d6a63c Mon Sep 17 00:00:00 2001 From: Eshed Shaham Date: Mon, 15 Nov 2021 14:22:22 +0200 Subject: [PATCH] NSInvocation+OCMAdditions: don't retain deallocating objects. Solves https://github.com/erikdoe/ocmock/issues/346. `allowsWeakReference` returns `NO` if the receiver is during deallocation. Not retaining deallocating objects would prevent crashing later when the retained arguments are released - including the previously deallocated objects. There are some classes that can never have weak references - these would also not be retained which might limit some OCMock functionality. --- Source/OCMock/NSInvocation+OCMAdditions.m | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/OCMock/NSInvocation+OCMAdditions.m b/Source/OCMock/NSInvocation+OCMAdditions.m index 61569546..9867ece1 100644 --- a/Source/OCMock/NSInvocation+OCMAdditions.m +++ b/Source/OCMock/NSInvocation+OCMAdditions.m @@ -66,7 +66,10 @@ - (void)retainObjectArgumentsExcludingObject:(id)objectToExclude NSMutableArray *retainedArguments = [[NSMutableArray alloc] init]; id target = [self target]; - if((target != nil) && (target != objectToExclude) && !object_isClass(target)) + // We don't want to retain a currently deallocating target, we check this by calling + // allowsWeakReference which returns NO in exactly this case. + if((target != nil) && (target != objectToExclude) && !object_isClass(target) && + [target allowsWeakReference]) { // Bad things will happen if the target is a block since it's not being // copied. There isn't a very good way to tell if an invocation's target @@ -109,7 +112,9 @@ - (void)retainObjectArgumentsExcludingObject:(id)objectToExclude // case do not retain the argument. Note: Even though the type is class the // argument could be a non-class, e.g. an instance of OCMArg. } - else + // We don't want to retain a currently deallocating object, we check this by calling + // allowsWeakReference which returns NO in exactly this case. + else if([argument allowsWeakReference]) { [retainedArguments addObject:argument]; }