2010-07-24 26 views
16

我使用以下代码根据“应用内购买编程指南”请求产品列表。它曾经在我的iPhone应用程序中正常工作,但现在每次请求产品列表时都会崩溃。从不调用代理方法(void)productsRequest:(SKProductsRequest **)request didReceiveResponse:(SKProductsResponse **)responseStoreKit SKProductsRequest Crash

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

正如我所说,它工作得很好,然后就停止工作。这是上述代码被调用时发生的崩溃。

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 

我不知道是什么导致objc_msgSend崩溃,或者它如何与StoreKit相关。我也不知道我添加或更改了哪些内容导致此简单代码停止工作。

回答

48

很可能的解释是,您设置为SKProductRequest对象代理的对象是否已被释放。

请求很可能需要几秒钟才能完成,而且这可能会超出委托对象的生命周期,因此您可能需要确保它足够长时间。

+0

的确是这个问题。这个问题刚刚在同一个答案中得到了解决,不知何故似乎已经消失了。 – ttarik 2011-04-20 06:30:51

+0

神话般的男人..ü保存了我很多的时间.. – 2016-07-13 07:01:49

+0

好吧,我了解代表可能会被取消分配,但你会如何解决? – impression7vx 2016-12-08 01:57:11

3

上述答案在技术上是正确的,但并不完整。正如Megastep所说:“您设置的SKProductsRequest代理对象可能已被释放。”因此,您正在向已被释放的对象发送消息。现在到实际的答案:

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

所以基本上,你可以在上面看到你并不需要释放productsRequest,因为它已经在委托回调方法释放。同样,您不需要调用productsRequest release,也不需要在viewDidUnload/dealloc方法中将其设置为Nil,因为如果在调用回调方法之前关闭视图,则可能会导致崩溃。