Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<__NSArrayM: 0x60000327cff0> was mutated while being enumerated #849

Closed
kennym opened this issue Nov 12, 2019 · 6 comments · Fixed by #957
Closed

<__NSArrayM: 0x60000327cff0> was mutated while being enumerated #849

kennym opened this issue Nov 12, 2019 · 6 comments · Fixed by #957
Labels
1️⃣ good first issue Good for newcomers ℹ needs more info Needs more detailed information to move forward

Comments

@kennym
Copy link
Contributor

kennym commented Nov 12, 2019

NSGenericException *** Collection <__NSArrayM: 0x283821110> was mutated while being enumerated. 
    Frameworks/CoreFoundation.framework/CoreFoundation ___exceptionPreprocess
    /usr/lib/libobjc.A.dylib _objc_exception_throw
    Frameworks/CoreFoundation.framework/CoreFoundation ___NSFastEnumerationMutationHandler
    /Users/runner/runners/2.158.0/work/1/s/node_modules/react-native-iap-3.2.3/ios/RNIapIos.m:305:5 -[RNIapIos productsRequest:didReceiveResponse:]
    Frameworks/StoreKit.framework/StoreKit ___27-[SKProductsRequest _start]_block_invoke_2
    /usr/lib/system/libdispatch.dylib __dispatch_call_block_and_release
    /usr/lib/system/libdispatch.dylib __dispatch_client_callout
    /usr/lib/system/libdispatch.dylib __dispatch_queue_override_invoke
    /usr/lib/system/libdispatch.dylib __dispatch_root_queue_drain
    /usr/lib/system/libdispatch.dylib __dispatch_worker_thread2
    /usr/lib/system/libsystem_pthread.dylib __pthread_wqthread
    /usr/lib/system/libsystem_pthread.dylib _start_wqthread

We see several instances of this error occurring in the wild. It might be us calling getProducts more than once in rapid succession, but I wonder if there's some defensive coding we could put in place, to prevent this error?

Version of react-native-iap

4.2.0

Version of react-native

0.61.4

Platforms you faced the error (IOS or Android or both?)

iOS

Expected behavior

No error

Actual behavior

Race condition

Tested environment (Emulator? Real Device?)

Real device/Emulator

Steps to reproduce the behavior

Unkown

@hyochan hyochan added 1️⃣ good first issue Good for newcomers ℹ needs more info Needs more detailed information to move forward labels Nov 13, 2019
@hyochan
Copy link
Owner

hyochan commented Nov 13, 2019

Thanks for the issue. I hope we could have minimal reproduction.

@tom-gurney
Copy link

I've noticed the same issue but only in release iOS versions, I can't replicate it at all in debug with the IAP sandbox, it seems to happen randomly and doesn't consistently crash and it's not affecting every user.

@kennym are you calling getAvailablePurchases() at all? As that seems to be what is causing the crash for me.

@hyochan I think for me it happens when I check if the user has an active subscription using the snippet from this thread: #275 (comment)

(I'm currently running react-native-iap 4.0.7)

@vischnabel
Copy link

Hey guys, how are you? I'm also currently experiencing this issue in production and, given that I'm not an Objective-C developer, I tried to look into the code to see what's happening.

-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
    for (SKProduct* prod in response.products) {
        [self addProduct:prod];
    }
    NSMutableArray* items = [NSMutableArray array];
    
    for (SKProduct* product in validProducts) {
        [items addObject:[self getProductObject:product]];
    }
    
    [self resolvePromisesForKey:RCTKeyForInstance(request) value:items];
}

The issue happens at the line

for (SKProduct* product in validProducts) {

and for what I have read, it has to do with multiple threads accessing the validProducts array at the same time, maybe because the method is being called multiple times in succession or something like that. On Stack Overflow, people have given 2 different solutions:

  • Use synchronised to ensure thread safety.
  • Copy the validProducts array before using it.

Do you think this is correct? Sorry if I'm being completely wrong about it, and thanks in advance.

@Chandrakala-B
Copy link

I am also facing the same problem. Could anyone help me with this

@kasl
Copy link

kasl commented Mar 19, 2020

In version react-native-iap@4.3.3 same issue. Occurs on various devices (iPhone 6S, X, 11 pro max, 7, 8 etc) and OS versions 13. *
@hyochan Are there any plans to fix this problem?

partiellkorrekt added a commit to partiellkorrekt/react-native-iap that referenced this issue Mar 23, 2020
Wrap every access to validProducts in an @synchronized-Block. This might impact the performance but it fixes the crashes described in Issue hyochan#849 for me.
@partiellkorrekt
Copy link
Contributor

partiellkorrekt commented Mar 23, 2020

@vischnabel I'm not an Objectice-C developer myself but I added @synchronized to every access to validProducts as you proposed in your answer. As far as I can tell, this fixes the problem for me.

I created the following pull-request: #957

hyochan pushed a commit that referenced this issue Mar 23, 2020
Wrap every access to validProducts in an @synchronized-Block. This might impact the performance but it fixes the crashes described in Issue #849 for me.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1️⃣ good first issue Good for newcomers ℹ needs more info Needs more detailed information to move forward
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants