2010-07-24 6 views
16

Ich verwende den folgenden Code, um eine Liste von Produkten gemäß dem In-App Purchase Programming Guide anzufordern. Früher funktionierte es in meiner iPhone-Anwendung gut, jetzt stürzt es jedoch jedes Mal ab, wenn die Produktliste angefordert wird. Die Delegate-Methode (void)productsRequest:(SKProductsRequest **)request didReceiveResponse:(SKProductsResponse **)response wird nie aufgerufen.StoreKit SKProductsRequest Crash

Wie gesagt, es funktionierte einwandfrei, dann hörte einfach auf zu arbeiten. Dies ist der Absturz, der auftritt, wenn der obige Code aufgerufen wird.

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 

Ich weiß nicht, was die objc_msgSend Absturz verursacht, oder wie man es StoreKit zusammenhängt. Ich habe auch keine Ahnung, was ich hinzugefügt oder geändert habe, was dazu geführt hat, dass dieser einfache Code nicht mehr funktioniert.

Antwort

48

Eine sehr wahrscheinliche Erklärung ist, ob das Objekt, das Sie als Delegat für das Objekt SKProductRequest festgelegt haben, bereits freigegeben wurde.

Es ist durchaus möglich, dass die Anforderung ein paar Sekunden dauert, und dies kann nach der Lebensdauer Ihres Delegatobjekts liegen. Sie sollten also sicherstellen, dass es lange genug bleibt.

+0

In der Tat war das das Problem. Dies wurde vor einiger Zeit mit der gleichen Antwort gelöst, irgendwie scheint das verschwunden zu sein. – ttarik

+0

Fabulous man .. U gespeichert eine Menge meiner Zeit .. –

+0

Okay, ich verstehe, dass der Delegierte freigegeben werden könnte, aber wie würden Sie das beheben? – impression7vx

3

Die obige Antwort ist technisch korrekt, aber sie ist nicht vollständig. Wie Megastep sagte: "Das Objekt, das Sie als Delegat für den SKProductsRequest festgelegt haben, wurde möglicherweise bereits freigegeben." Daher senden Sie eine Nachricht an ein Objekt, das bereits freigegeben wurde. Jetzt auf die tatsächliche Antwort:

- (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]; 
} 

Also im Grunde wie Sie sehen können über Sie nicht productsRequest müssen freizugeben, da es bereits in der Delegat Callback-Methode freigegeben wird. Auch hier müssen Sie die releaseRequest-Version nicht aufrufen oder sie in der Methode "viewDidUnload/dealloc" auf Nil setzen, da dies zu einem Absturz führen kann, wenn Sie die Ansicht vor dem Aufruf der Callback-Methode abbrechen.