2010-07-24 7 views
16

J'utilise le code suivant pour demander une liste de produits conformément au Guide de programmation des achats intégrés. Il fonctionnait très bien dans mon application iPhone, mais maintenant il se bloque chaque fois que la liste de produits est demandée. La méthode déléguée (void)productsRequest:(SKProductsRequest **)request didReceiveResponse:(SKProductsResponse **)response n'est jamais appelée.StoreKit SKProductsRequest Crash

SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"my.product.identifier"]]; 
[request setDelegate:self]; 
[request start]; 

Comme je l'ai dit, cela a fonctionné parfaitement bien, puis juste arrêté de fonctionner. C'est le crash qui se produit lorsque le code ci-dessus est appelé.

Exception Type: EXC_BAD_ACCESS (SIGBUS) 
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000011 
Crashed Thread: 0 

Thread 0 Crashed: 
0 libobjc.A.dylib     0x000034f8 objc_msgSend + 24 
1 StoreKit      0x00003e18 -[SKProductsRequest handleFinishResponse:returningError:] + 40 
2 StoreKit      0x000050c4 -[SKRequest _requestFinishedNotification:] + 152 
3 Foundation      0x00019b9a _nsnote_callback + 150 
4 CoreFoundation     0x0006c2de __CFXNotificationPost_old + 390 
5 CoreFoundation     0x0001ab32 _CFXNotificationPostNotification + 122 
6 Foundation      0x000048e4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 64 
7 AppSupport      0x0000bb42 -[CPDistributedNotificationCenter deliverNotification:userInfo:] + 38 
8 AppSupport      0x0000cf66 _CPDNDeliverNotification + 198 
9 AppSupport      0x0000ba4a _XDeliverNotification + 110 
10 AppSupport      0x00002e82 migHelperRecievePortCallout + 122 
11 CoreFoundation     0x000742ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 22 
12 CoreFoundation     0x000761d6 __CFRunLoopDoSource1 + 158 
13 CoreFoundation     0x0007718e __CFRunLoopRun + 574 
14 CoreFoundation     0x0001e0bc CFRunLoopRunSpecific + 220 
15 CoreFoundation     0x0001dfca CFRunLoopRunInMode + 54 
16 GraphicsServices    0x00003f88 GSEventRunModal + 188 
17 UIKit       0x00007b40 -[UIApplication _run] + 564 
18 UIKit       0x00005fb8 UIApplicationMain + 964 
19 myapp       0x00002fae main (main.m:13) 
20 myapp       0x00002f58 start + 32 

Thread 1: 
0 libSystem.B.dylib    0x00034e84 kevent + 24 
1 libSystem.B.dylib    0x00102a48 _dispatch_mgr_invoke + 88 
2 libSystem.B.dylib    0x00102494 _dispatch_queue_invoke + 96 
3 libSystem.B.dylib    0x00102634 _dispatch_worker_thread2 + 120 
4 libSystem.B.dylib    0x0008b53c _pthread_wqthread + 392 
5 libSystem.B.dylib    0x00082b6c start_wqthread + 0 

Thread 2: 
0 libSystem.B.dylib    0x00000ab0 mach_msg_trap + 20 
1 libSystem.B.dylib    0x00002f94 mach_msg + 60 
2 CoreFoundation     0x00074b18 __CFRunLoopServiceMachPort + 88 
3 CoreFoundation     0x000770e0 __CFRunLoopRun + 400 
4 CoreFoundation     0x0001e0bc CFRunLoopRunSpecific + 220 
5 CoreFoundation     0x0001dfca CFRunLoopRunInMode + 54 
6 WebCore       0x0000370c RunWebThread(void*) + 552 
7 libSystem.B.dylib    0x0008af80 _pthread_start + 364 
8 libSystem.B.dylib    0x0007d014 thread_start + 0 

Thread 3: 
0 libSystem.B.dylib    0x00000ab0 mach_msg_trap + 20 
1 libSystem.B.dylib    0x00002f94 mach_msg + 60 
2 CoreFoundation     0x00074b18 __CFRunLoopServiceMachPort + 88 
3 CoreFoundation     0x000770e0 __CFRunLoopRun + 400 
4 CoreFoundation     0x0001e0bc CFRunLoopRunSpecific + 220 
5 CoreFoundation     0x0001dfca CFRunLoopRunInMode + 54 
6 Foundation      0x0003c316 +[NSURLConnection(NSURLConnectionReallyInternal) _resourceLoadLoop:] + 210 
7 Foundation      0x0000c612 -[NSThread main] + 42 
8 Foundation      0x00092140 __NSThread__main__ + 908 
9 libSystem.B.dylib    0x0008af80 _pthread_start + 364 
10 libSystem.B.dylib    0x0007d014 thread_start + 0 

Thread 4: 
0 libSystem.B.dylib    0x00029f24 select$DARWIN_EXTSN + 20 
1 CoreFoundation     0x0007aa54 __CFSocketManager + 340 
2 libSystem.B.dylib    0x0008af80 _pthread_start + 364 
3 libSystem.B.dylib    0x0007d014 thread_start + 0 

Je ne sais pas ce qui est à l'origine du crash objc_msgSend, ou comment il est lié à StoreKit. Je n'ai également aucune idée de ce que j'ai ajouté ou changé, ce qui a fait que ce simple code a cessé de fonctionner.

Répondre

48

Une explication très probable consiste à savoir si l'objet que vous avez défini en tant que délégué pour l'objet SKProductRequest a déjà été désalloué.

Il est tout à fait possible que la requête prenne quelques secondes pour se terminer, et que la durée de vie de votre objet délégué est peut-être dépassée. Vous pouvez donc vous assurer qu'il reste suffisamment longtemps.

+0

En effet, c'était le problème. Cela a été résolu il ya quelque temps avec à peu près la même réponse, d'une certaine façon cela semble avoir disparu. – ttarik

+0

Fabuleux homme .. U sauvé beaucoup de mon temps .. –

+0

Bon, je comprends que le délégué pourrait être désengagé, mais comment voulez-vous résoudre ce problème? – impression7vx

3

La réponse ci-dessus est techniquement correcte mais elle n'est pas complète. Comme l'a dit Megastep, "l'objet que vous avez défini en tant que délégué pour SKProductsRequest a peut-être déjà été désalloué." Par conséquent, vous envoyez un message à un objet qui a déjà été désalloué. Maintenant, sur la réponse réelle:

- (void)requestProUpgradeProductData { 
    NSSet *productIdentifiers = //Your Product IDs go here 

    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers]; 
    productsRequest.delegate = self; 
    [productsRequest start]; 

    // we will release the request object in the delegate callback 
} 

#pragma mark - 
#pragma mark SKProductRequest Delegate Methods 

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse(SKProductsResponse *)response { 
self.products = response.products; 
//NSLog(@"%i",[products count]); 
proUpgradeProduct = [products count] == 4 ? [[products objectAtIndex:0] retain] : nil; 
if (proUpgradeProduct) 
{ 
    //Do your stuff here... 
} 

for (NSString *invalidProductId in response.invalidProductIdentifiers) 
{ 
    //NSLog(@"Invalid product id: %@" , invalidProductId); 
} 

// finally release the reqest we alloc/init’ed in requestProUpgradeProductData 
[productsRequest release]; 

[[NSNotificationCenter defaultCenter] postNotificationName:kInAppPurchaseManagerProductsFetchedNotification object:self userInfo:nil]; 
} 

Donc, fondamentalement, comme vous pouvez le voir ci-dessus, vous n'avez pas besoin de libérer productsRequest parce qu'il est déjà libéré dans la méthode de rappel de délégué. Encore une fois, vous n'avez pas besoin d'appeler la version de productsRequest ou de la définir comme nulle dans la méthode viewDidUnload/dealloc car cela pourrait provoquer un plantage si vous fermez la vue avant que la méthode de rappel ne soit appelée.