Pracuję nad niektórymi IAP using this tutorial.Program obsługi zakończenia powodujący EXC_BAD_ACCESS, gdy ta sama metoda jest wywoływana dwukrotnie
pierwsze I pobrania produktów z tym:
-(void)fetchAvailableProductsFirstLoad:(BOOL)firstTimeLoading {
[[IAPHelper sharedInstance] requestProductsWithCompletionHandler:^(BOOL success, NSArray *products) { ...
pomocniczy działa następujące:
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
@synchronized(self) {
// 1
_completionHandler = [completionHandler copy];
// 2
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
}
Gdy produkty są zwrócone lub nie powiodła się nazywa następujące:
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(@"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(@"Found product: %@ %@ %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(@"Failed to load list of products.");
NSLog(@"Error: %@",error);
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
Numer
Problem występuje, gdy użytkownik uruchamia pobieranie lub produkty dwa razy. Na przykład produkty pobierania są wywoływane w viewDidLoad, ale jeśli użytkownik ma złe/wolne połączenie i nawiguje z dala, a następnie z powrotem do kontrolera. Początkowe pobieranie nie zostanie anulowane, dlatego są dwa uruchomione.
Uważam, że problem występuje, gdy drugi jest zwracany, a wskaźnik się zmienił/nie istnieje/jest uszkodzony.
EXC_BAD_ACCESS 2 kod błędu pojawia się na właściwej linii:
_completionHandler(YES, skProducts);
LUB
_completionHandler(NO, nil);
Dzięki, użyłem części obu odpowiedzi, ale to było najbliżej. Dodałem także dodatkową metodę '- (void) cancelProductRequest { [_productsRequest cancel]; _productsRequest = nil; } 'która anuluje bieżące żądanie, jeśli odejdzie od tego kontrolera, aby zapisać, że kiedykolwiek istnieje wiele żądań. – StuartM
Świetne @StuartM, zdecydowanie najlepiej anulować żądanie, jeśli go nie potrzebujesz. Cieszę się, że mogłem pomóc! – stefandouganhyde