сообщение отправлено на освобожденный экземпляр в приложении iphone - PullRequest
3 голосов
/ 06 апреля 2011

Я реализовал покупки в своем приложении, и в настоящее время я сталкиваюсь с критической ошибкой. Представьте код ниже

@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, когда я покидаю представление, а затемВернись к нему, я получаю

-[Credits respondsToSelector:]: message sent to deallocated instance 0x1a8810

Это вызывает у меня головную боль!Я считаю, что это проблема управления памятью, но я новичок в этом и не могу найти проблему: (

Ответы [ 5 ]

2 голосов
/ 16 декабря 2011

У меня была та же ошибка, но в коде неправильно, когда вы выделяете и инициируете запрос de products:

productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet     setWithObject:@"com.2sms.twosmsapp.credits.1"]];
    productsRequest.delegate = self;
    [productsRequest start];

, а в dealloc только освобождайте productsRequest до того, как произойдетВ действительности, productsRequest может вызывать делегата, представление которого не существует -> ОШИБКА

Единственное, что предотвращает эту ошибку - это установить для делегата значение nil перед выпуском:

productsRequest.delegate = nil;
[productsRequest release];

Это решит мою проблему.

Надеюсь, это поможет.

0 голосов
/ 14 июля 2015

У меня была та же проблема, довольно просто решить:

 -(void)dealloc{

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}

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

0 голосов
/ 06 апреля 2011

Ошибка предполагает, что вы пытаетесь получить доступ к чему-то, что было выпущено. Поэтому убедитесь, что вы не release объекты, пока вы не уверены, что они больше не нужны. В вашем случае, когда вы возвращаетесь к представлению, вы пытаетесь использовать освобожденный объект, поэтому, пожалуйста, проверьте выпуск ваших объектов.

0 голосов
/ 06 апреля 2011

Похоже, ваш объект Credits был освобожден до того, как вы его закончили.Попробуйте включить переменную окружения NSZombieEnabled для отслеживания освобожденных объектов и отправляемых им сообщений.Просто обязательно выключите NSZombieEnabled, когда вы закончите!

Кроме того, если вы используете сборщик мусора, убедитесь, что у вас всегда есть сильная ссылка на объект Credits.Это будет препятствовать GC выпускать и освобождать его, если GC включен.

0 голосов
/ 06 апреля 2011

Я думаю, в классе Credit вы используете любой выпущенный экземпляр.Проверьте ваши выпущенные компоненты.Может быть две причины для одного и того же случая: 1. Вы используете любой экземпляр без его выделения и инициализации.или 2. Вы используете любой экземпляр, который уже выпущен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...