сообщение, отправленное освобожденному экземпляру при покупке приложения iphone

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

Вы больше не должны получать ошибку