#iphone #objective-c #cocoa-touch #ios4
#iPhone #objective-c #cocoa-touch #ios4
Вопрос:
Я внедрил покупки в приложении в свое приложение, и в настоящее время я сталкиваюсь с критической ошибкой, смотрите код ниже
@implementation Credits
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
if ([SKPaymentQueue canMakePayments]) {
NSLog(@"PARENTAL CONTROL DISABLED");
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.2sms.twosmsapp.credits.1"]];
productsRequest.delegate = self;
[productsRequest start];
}
else {
NSLog(@"PARENTAL CONTROL ENABLED");
}
[super viewDidLoad];
}
-(IBAction)purchase100Credits{
SKPayment *payment = [SKPayment paymentWithProductIdentifier:@"com.2sms.twosmsapp.credits.1"];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
SKProduct *validProduct = nil;
int count = [response.products count];
if(count > 0)
{
validProduct = [response.products objectAtIndex:0];
}
else {
NSLog(@"NO PRODUCTS AVAILIABLE");
}
}
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
for(SKPaymentTransaction *transaction in transactions)
{
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStatePurchased:
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(@"AN ERROR ENCOUNTERED");
}
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
break;
}
}
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[productsRequest release];
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
[super dealloc];
}
Кнопка успешно получает информацию для itunes Store, однако, когда я покидаю просмотр, а затем возвращаюсь к нему, я получаю
-[Credits respondsToSelector:]: message sent to deallocated instance 0x1a8810
У меня от этого болит голова! я считаю, что это проблема с управлением памятью, но я новичок в этом и не могу найти проблему: (
Ответ №1:
У меня была та же ошибка, но в коде неверно, когда вы выделяете и инициируете запрос продуктов de:
productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObject:@"com.2sms.twosmsapp.credits.1"]];
productsRequest.delegate = self;
[productsRequest start];
и при освобождении только освобождайте productsRequest, прежде чем произойдет реальное размещение, productsRequest может вызвать делегат, представление, которое не существует -> ОШИБКА
Единственное, что предотвращает эту ошибку, — установить для делегата значение nil перед выпуском:
productsRequest.delegate = nil;
[productsRequest release];
Это решает мою проблему.
Надеюсь, это поможет.
Ответ №2:
Я думаю, что в классе Credit вы используете любой выпущенный экземпляр. Проверьте выпущенные компоненты. Для одного и того же случая может быть 2 причины: 1. Вы используете какой-либо экземпляр без его выделения и инициализации. или 2. Вы используете любой экземпляр, который уже выпущен.
Ответ №3:
Ошибка предполагает, что вы пытаетесь получить доступ к чему-то, что было выпущено. Поэтому убедитесь, что вы не release
используете объекты, пока не будете уверены, что они больше не нужны. В вашем случае, когда вы возвращаетесь к просмотру, вы пытаетесь использовать объект, который выпущен, поэтому, пожалуйста, проверьте выпуск ваших объектов.
Ответ №4:
Похоже, что ваш объект Credits освобождается до того, как вы закончите его использовать. Попробуйте включить переменную среды NSZombieEnabled для отслеживания освобожденных объектов и отправленных им сообщений. Просто не забудьте отключить NSZombieEnabled, когда закончите!
Кроме того, если вы используете сборку мусора, убедитесь, что у вас всегда есть надежная ссылка на объект Credits. Это не позволит GC выпустить и освободить его, если GC включен.
Ответ №5:
У меня была такая же проблема, которую на самом деле довольно просто решить:
-(void)dealloc{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
Вы больше не должны получать ошибку