使用Xcode 5,iOS 7
我有一个类(LHBBuyService)来处理应用内购买。它有相应的商店前视图来购买产品。
如果用户打开商店前视图然后等待响应,它通常很有效。
但是 当用户打开商店前视图,然后在App Store发回响应之前快速导航,并打开其他一些视图。
它在模拟器和设备上崩溃。
我收到了这个崩溃日志:
[LHBBuyService respondsToSelector:]:发送到deallocated的消息 实例0x2e7b4eb0
我想也许原因是加载商店前视图时,我在其viewDidLoad()函数中添加了一个观察者:
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
但是当它被导航时,它的委托也用于从App Store接收消息,所以我删除了viewWillDisappear中的观察者:
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
但我仍然崩溃,任何人都可以帮助我吗? 非常感谢!
LHBBuyService源代码:
#import "LHBBuyService.h"
#import "MBProgressHUD.h"
#define Rgb2UIColor(r, g, b) [UIColor colorWithRed:((r) / 255.0) green:((g) / 255.0) blue:((b) / 255.0) alpha:1.0]
@implementation LHBBuyService{
PoetryDao *poetryDao;
}
-(void) viewDidLoad{
self.view.backgroundColor = Rgb2UIColor(102, 153, 204);
self.msgLabel.backgroundColor = Rgb2UIColor(102, 153, 204);
poetryDao = [[PoetryDao alloc] init];
_buyBtn.enabled = NO;
_restoreBtn.enabled = NO;
_productID = @"com.lihappy.poetry.iphone";
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
if ([SKPaymentQueue canMakePayments])
{
self.request = [[SKProductsRequest alloc]
initWithProductIdentifiers:
[NSSet setWithObject:self.productID]];
self.request.delegate = self;
[self.request start];
//发起请求1,请求待购买的产品信息,开始等待
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
}
else
_msgLabel.text = @"Please enable In App Purchase in Settings";
}
-(void) viewWillDisappear:(BOOL)animated{
[MBProgressHUD hideHUDForView:self.view animated:YES];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
- (IBAction)buyItem:(id)sender {
@try{
SKPayment *payment = [SKPayment paymentWithProduct:_product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
//发起购买请求2
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
}@catch(NSException *e){
NSLog(@"%@", e);
}
}
- (IBAction)restoreBtnPressed:(id)sender {
@try {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
//发起恢复请求
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
@finally {
}
}
#pragma mark -
#pragma mark SKProductsRequestDelegate
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
//收到请求1返回的产品信息
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSArray *products = response.products;
if (products.count != 0)
{
_product = products[0];
_buyBtn.enabled = YES;
_restoreBtn.enabled = YES;
} else {
_msgLabel.text = (@"无法连接苹果服务器,请重试");
}
}
-(void)request:(SKRequest *)request didFailWithError:(NSError *)error{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(@"%@", error);
_msgLabel.text = [NSString stringWithFormat:@"请求失败,请连接网络,或注销已登陆的app store帐号后重试!%@", error];
}
-(void) paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(@"%@", error);
_msgLabel.text = [NSString stringWithFormat:@"没有已购买的产品,请点击“购买”按钮!!%@", error];
}
-(void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(@"transactions finished.");
}
-(void) requestDidFinish:(SKRequest *)request{
[MBProgressHUD hideHUDForView:self.view animated:YES];
NSLog(@"request did finish.");
}
-(void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
//收到购买请求2的返回
[MBProgressHUD hideHUDForView:self.view animated:YES];
for (SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
[self unlockFeature];
[[SKPaymentQueue defaultQueue]
finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
_msgLabel.text = @"请求失败,请连接网络,或注销已登陆的app store帐号后重试";
NSLog(@"请求失败,请连接网络,或注销已登陆的app store帐号后重试");
[[SKPaymentQueue defaultQueue]
finishTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
_msgLabel.text = @"已经买过,诗词已解锁";
NSLog(@"already have");
[self unlockFeature];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
_msgLabel.text = @"处理中...";
NSLog(@"purchasing...");
break;
default:
break;
}
}
}
-(void)unlockFeature
{
_msgLabel.text = @"购买成功!所有诗词已解锁!";
//update database
BOOL isUpdateOk = [poetryDao updateAllLicense:1];
if(isUpdateOk){
NSArray *viewControllers = self.navigationController.viewControllers;
UIViewController *rootViewController = [viewControllers objectAtIndex:viewControllers.count - 2];
ListTableViewController *vc = (ListTableViewController *)rootViewController;
vc.poetryArray = [[[PoetryDao alloc] init] getAllListWithBasicInfo];
[vc.tableView reloadData];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"购买成功" message:@"所有诗词已解锁" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
[self performSelector:@selector(dismissAlert:) withObject:alert afterDelay:1];
}else{
_msgLabel.text = @"解锁诗库失败,请重试";
}
}
-(void)dismissAlert:(UIAlertView*)alert{
[alert dismissWithClickedButtonIndex:-1 animated:YES];
}
@end
一些相关的崩溃日志:
CoreFoundation`___forwarding___:
0x1fa3510: pushl %ebp
0x1fa3511: movl %esp, %ebp
0x1fa3513: pushl %ebx
0x1fa3514: pushl %edi
0x1fa3515: pushl %esi
0x1fa3516: subl $60, %esp
0x1fa3519: calll 0x1fa351e ; ___forwarding___ + 14
0x1fa351e: popl %eax
0x1fa351f: movl %eax, -16(%ebp)
0x1fa3522: cmpl $0, 12(%ebp)
0x1fa3526: setne %al
0x1fa3529: movzbl %al, %esi
0x1fa352c: movl 8(%ebp), %ecx
0x1fa352f: movl 4(%ecx,%esi,4), %eax
0x1fa3533: movl %eax, -20(%ebp)
0x1fa3536: movl (%ecx,%esi,4), %ebx
0x1fa3539: movl %ebx, (%esp)
0x1fa353c: calll 0x209b4da ; symbol stub for: object_getClass
0x1fa3541: movl %eax, %edi
0x1fa3543: movl %edi, -28(%ebp)
0x1fa3546: movl %edi, (%esp)
0x1fa3549: calll 0x209b408 ; symbol stub for: class_getName
0x1fa354e: movl %eax, -24(%ebp)
0x1fa3551: movl -16(%ebp), %eax
0x1fa3554: movl 1394666(%eax), %eax
0x1fa355a: movl %eax, -32(%ebp)
0x1fa355d: movl %eax, 4(%esp)
0x1fa3561: movl %edi, (%esp)
0x1fa3564: calll 0x209b41a ; symbol stub for: class_respondsToSelector
0x1fa3569: testb %al, %al
0x1fa356b: je 0x1fa358f ; ___forwarding___ + 127
0x1fa356d: movl -20(%ebp), %eax
0x1fa3570: movl %eax, 8(%esp)
0x1fa3574: movl -32(%ebp), %eax
0x1fa3577: movl %eax, 4(%esp)
0x1fa357b: movl %ebx, (%esp)
0x1fa357e: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa3583: testl %eax, %eax
0x1fa3585: je 0x1fa358f ; ___forwarding___ + 127
0x1fa3587: cmpl %ebx, %eax
0x1fa3589: jne 0x1fa3788 ; ___forwarding___ + 632
0x1fa358f: movl -16(%ebp), %esi
0x1fa3592: leal 1071604(%esi), %eax
0x1fa3598: movl %eax, 4(%esp)
0x1fa359c: movl -24(%ebp), %edi
0x1fa359f: movl %edi, (%esp)
0x1fa35a2: movl $10, 8(%esp)
0x1fa35aa: calll 0x209bbfa ; symbol stub for: strncmp
0x1fa35af: testl %eax, %eax
0x1fa35b1: je 0x1fa379d ; ___forwarding___ + 653
0x1fa35b7: movl 1394638(%esi), %esi
0x1fa35bd: movl %esi, 4(%esp)
0x1fa35c1: movl -28(%ebp), %edi
0x1fa35c4: movl %edi, (%esp)
0x1fa35c7: calll 0x209b41a ; symbol stub for: class_respondsToSelector
0x1fa35cc: testb %al, %al
0x1fa35ce: je 0x1fa3816 ; ___forwarding___ + 774
0x1fa35d4: movl -20(%ebp), %eax
0x1fa35d7: movl %eax, 8(%esp)
0x1fa35db: movl %esi, 4(%esp)
0x1fa35df: movl %ebx, %edi
0x1fa35e1: movl %edi, (%esp)
0x1fa35e4: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa35e9: testl %eax, %eax
0x1fa35eb: je 0x1fa3870 ; ___forwarding___ + 864
0x1fa35f1: movl %edi, -32(%ebp)
0x1fa35f4: movl -16(%ebp), %ebx
0x1fa35f7: movl 1394614(%ebx), %ecx
0x1fa35fd: movl %ecx, 4(%esp)
0x1fa3601: movl %eax, (%esp)
0x1fa3604: movl %eax, -24(%ebp)
0x1fa3607: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa360c: movl %eax, -28(%ebp)
0x1fa360f: movl (%eax), %eax
0x1fa3611: movzwl 26(%eax), %eax
0x1fa3615: shrl $6, %eax
0x1fa3618: andl $1, %eax
0x1fa361b: movl 12(%ebp), %ecx
0x1fa361e: cmpl %ecx, %eax
0x1fa3620: movl -20(%ebp), %eax
0x1fa3623: je 0x1fa367b ; ___forwarding___ + 363
0x1fa3625: movl %eax, (%esp)
0x1fa3628: leal 1042458(%ebx), %eax
0x1fa362e: movl %eax, -20(%ebp)
0x1fa3631: leal 1096367(%ebx), %esi
0x1fa3637: testl %ecx, %ecx
0x1fa3639: movl %esi, %edi
0x1fa363b: cmovnel %eax, %edi
0x1fa363e: calll 0x209b4fe ; symbol stub for: sel_getName
0x1fa3643: movl -28(%ebp), %ecx
0x1fa3646: movl (%ecx), %ecx
0x1fa3648: movzwl 26(%ecx), %ecx
0x1fa364c: movl %edi, 16(%esp)
0x1fa3650: movl %eax, 8(%esp)
0x1fa3654: leal 1414454(%ebx), %eax
0x1fa365a: movl %eax, 4(%esp)
0x1fa365e: andl $64, %ecx
0x1fa3661: shrl $6, %ecx
0x1fa3664: testw %cx, %cx
0x1fa3667: cmovnel -20(%ebp), %esi
0x1fa366b: movl %esi, 12(%esp)
0x1fa366f: movl $4, (%esp)
0x1fa3676: calll 0x1fda310 ; CFLog
0x1fa367b: movl 1395506(%ebx), %eax
0x1fa3681: movl 1394646(%ebx), %ecx
0x1fa3687: movl 8(%ebp), %edx
0x1fa368a: movl %edx, 12(%esp)
0x1fa368e: movl -24(%ebp), %edx
0x1fa3691: movl %edx, 8(%esp)
0x1fa3695: movl %ecx, 4(%esp)
0x1fa3699: movl %eax, (%esp)
0x1fa369c: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa36a1: movl %eax, -20(%ebp)
0x1fa36a4: movl %ebx, %esi
0x1fa36a6: movl -32(%ebp), %ebx
0x1fa36a9: movl %ebx, (%esp)
0x1fa36ac: calll 0x209b4da ; symbol stub for: object_getClass
0x1fa36b1: movl 1394670(%esi), %edi
0x1fa36b7: movl %edi, 4(%esp)
0x1fa36bb: movl %eax, (%esp)
0x1fa36be: calll 0x209b41a ; symbol stub for: class_respondsToSelector
0x1fa36c3: testb %al, %al
0x1fa36c5: je 0x1fa36dc ; ___forwarding___ + 460
0x1fa36c7: movl -20(%ebp), %eax
0x1fa36ca: movl %eax, 8(%esp)
0x1fa36ce: movl %edi, 4(%esp)
0x1fa36d2: movl %ebx, (%esp)
0x1fa36d5: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa36da: jmp 0x1fa3702 ; ___forwarding___ + 498
0x1fa36dc: movl %ebx, (%esp)
0x1fa36df: calll 0x209b4e0 ; symbol stub for: object_getClassName
0x1fa36e4: movl %eax, 12(%esp)
0x1fa36e8: movl %ebx, 8(%esp)
0x1fa36ec: leal 1414470(%esi), %eax
0x1fa36f2: movl %eax, 4(%esp)
0x1fa36f6: movl $4, (%esp)
0x1fa36fd: calll 0x1fda310 ; CFLog
0x1fa3702: movl 1428286(%esi), %eax
0x1fa3708: movl -20(%ebp), %ecx
0x1fa370b: cmpb $0, (%ecx,%eax)
0x1fa370f: movl -28(%ebp), %eax
0x1fa3712: movl %ecx, %ebx
0x1fa3714: je 0x1fa374c ; ___forwarding___ + 572
0x1fa3716: movl (%eax), %eax
0x1fa3718: testb $-128, 26(%eax)
0x1fa371c: je 0x1fa374c ; ___forwarding___ + 572
0x1fa371e: movl 1428278(%esi), %ecx
0x1fa3724: movl (%ebx,%ecx), %ecx
0x1fa3727: movzbl 24(%eax), %edx
0x1fa372b: addl 20(%eax), %edx
0x1fa372e: movl (%ecx,%edx), %ecx
0x1fa3731: movl 8(%ebp), %edi
0x1fa3734: movl (%edi,%edx), %edx
0x1fa3737: movl (%eax), %eax
0x1fa3739: movl 8(%eax), %eax
0x1fa373c: movl %eax, 8(%esp)
0x1fa3740: movl %ecx, 4(%esp)
0x1fa3744: movl %edx, (%esp)
0x1fa3747: calll 0x209ba0e ; symbol stub for: memmove
0x1fa374c: movl 1428274(%esi), %eax
0x1fa3752: movl (%ebx,%eax), %edi
0x1fa3755: movl 1394674(%esi), %eax
0x1fa375b: movl %eax, 4(%esp)
0x1fa375f: movl -24(%ebp), %eax
0x1fa3762: movl %eax, (%esp)
0x1fa3765: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa376a: movsbl (%eax), %eax
0x1fa376d: cmpl $68, %eax
0x1fa3770: je 0x1fa377b ; ___forwarding___ + 619
0x1fa3772: cmpl $100, %eax
0x1fa3775: jne 0x1fa377f ; ___forwarding___ + 623
0x1fa3777: fldl (%edi)
0x1fa3779: jmp 0x1fa3793 ; ___forwarding___ + 643
0x1fa377b: fldt (%edi)
0x1fa377d: jmp 0x1fa3793 ; ___forwarding___ + 643
0x1fa377f: cmpl $102, %eax
0x1fa3782: jne 0x1fa3793 ; ___forwarding___ + 643
0x1fa3784: flds (%edi)
0x1fa3786: jmp 0x1fa3793 ; ___forwarding___ + 643
0x1fa3788: shll $2, %esi
0x1fa378b: movl 8(%ebp), %ecx
0x1fa378e: movl %eax, (%ecx,%esi)
0x1fa3791: xorl %edi, %edi
0x1fa3793: movl %edi, %eax
0x1fa3795: addl $60, %esp
0x1fa3798: popl %esi
0x1fa3799: popl %edi
0x1fa379a: popl %ebx
0x1fa379b: popl %ebp
0x1fa379c: ret
0x1fa379d: movl 1330030(%esi), %eax
0x1fa37a3: cmpb $0, (%eax)
0x1fa37a6: je 0x1fa37e0 ; ___forwarding___ + 720
0x1fa37a8: movl %ebx, 4(%esp)
0x1fa37ac: movl $0, 24(%esp)
0x1fa37b4: movl $0, 20(%esp)
0x1fa37bc: movl $0, 16(%esp)
0x1fa37c4: movl $0, 12(%esp)
0x1fa37cc: movl $0, 8(%esp)
0x1fa37d4: movl $21, (%esp)
0x1fa37db: calll 0x1f54050 ; __CFRecordAllocationEvent
0x1fa37e0: movl -20(%ebp), %eax
0x1fa37e3: movl %eax, (%esp)
0x1fa37e6: calll 0x209b4fe ; symbol stub for: sel_getName
0x1fa37eb: movl %ebx, 16(%esp)
0x1fa37ef: movl %eax, 12(%esp)
0x1fa37f3: addl $10, %edi
0x1fa37f6: movl %edi, 8(%esp)
0x1fa37fa: leal 1414374(%esi), %eax
0x1fa3800: movl %eax, 4(%esp)
0x1fa3804: movl $3, (%esp)
0x1fa380b: calll 0x1fda310 ; CFLog
0x1fa3810: int3
0x1fa3811: jmp 0x1fa390c ; ___forwarding___ + 1020
0x1fa3816: movl %edi, (%esp)
0x1fa3819: calll 0x209b40e ; symbol stub for: class_getSuperclass
0x1fa381e: movl %eax, %edi
0x1fa3820: movl %ebx, (%esp)
0x1fa3823: calll 0x209b4e0 ; symbol stub for: object_getClassName
0x1fa3828: movl %eax, %esi
0x1fa382a: testl %edi, %edi
0x1fa382c: jne 0x1fa384d ; ___forwarding___ + 829
0x1fa382e: movl %ebx, (%esp)
0x1fa3831: calll 0x209b4e0 ; symbol stub for: object_getClassName
0x1fa3836: movl %eax, 16(%esp)
0x1fa383a: movl %esi, 12(%esp)
0x1fa383e: movl %ebx, 8(%esp)
0x1fa3842: movl -16(%ebp), %eax
0x1fa3845: leal 1414390(%eax), %eax
0x1fa384b: jmp 0x1fa385e ; ___forwarding___ + 846
0x1fa384d: movl %esi, 12(%esp)
0x1fa3851: movl %ebx, 8(%esp)
0x1fa3855: movl -16(%ebp), %eax
0x1fa3858: leal 1414406(%eax), %eax
0x1fa385e: movl %eax, 4(%esp)
0x1fa3862: movl $4, (%esp)
0x1fa3869: calll 0x1fda310 ; CFLog
0x1fa386e: movl %ebx, %edi
0x1fa3870: movl -20(%ebp), %ebx
0x1fa3873: movl %ebx, (%esp)
0x1fa3876: calll 0x209b4fe ; symbol stub for: sel_getName
0x1fa387b: movl %eax, %esi
0x1fa387d: movl %esi, (%esp)
0x1fa3880: calll 0x209b504 ; symbol stub for: sel_getUid
0x1fa3885: cmpl %ebx, %eax
0x1fa3887: je 0x1fa38ae ; ___forwarding___ + 926
0x1fa3889: movl %eax, 16(%esp)
0x1fa388d: movl %esi, 12(%esp)
0x1fa3891: movl %ebx, 8(%esp)
0x1fa3895: movl -16(%ebp), %eax
0x1fa3898: leal 1414422(%eax), %eax
0x1fa389e: movl %eax, 4(%esp)
0x1fa38a2: movl $4, (%esp)
0x1fa38a9: calll 0x1fda310 ; CFLog
0x1fa38ae: movl %edi, (%esp)
0x1fa38b1: calll 0x209b4da ; symbol stub for: object_getClass
0x1fa38b6: movl -16(%ebp), %ecx
0x1fa38b9: movl 1394166(%ecx), %esi
0x1fa38bf: movl %esi, 4(%esp)
0x1fa38c3: movl %eax, (%esp)
0x1fa38c6: calll 0x209b41a ; symbol stub for: class_respondsToSelector
0x1fa38cb: testb %al, %al
0x1fa38cd: jne 0x1fa38fb ; ___forwarding___ + 1003
0x1fa38cf: movl %edi, (%esp)
0x1fa38d2: calll 0x209b4e0 ; symbol stub for: object_getClassName
0x1fa38d7: movl %eax, 12(%esp)
0x1fa38db: movl %edi, 8(%esp)
0x1fa38df: movl -16(%ebp), %eax
0x1fa38e2: leal 1414438(%eax), %eax
0x1fa38e8: movl %eax, 4(%esp)
0x1fa38ec: movl $4, (%esp)
0x1fa38f3: calll 0x1fda310 ; CFLog
0x1fa38f8: int3
0x1fa38f9: jmp 0x1fa390c ; ___forwarding___ + 1020
0x1fa38fb: movl %ebx, 8(%esp)
0x1fa38ff: movl %esi, 4(%esp)
0x1fa3903: movl %edi, (%esp)
0x1fa3906: calll 0x209b48c ; symbol stub for: objc_msgSend
0x1fa390b: int3
0x1fa390c: calll 0x209b8e2 ; symbol stub for: getpid
0x1fa3911: movl %eax, (%esp)
0x1fa3914: movl $9, 4(%esp)
0x1fa391c: calll 0x209b930 ; symbol stub for: kill
0x1fa3921: nopw %cs:(%eax,%eax)