【问题标题】:[AppCommons respondsToSelector:]: message sent to deallocated instance[AppCommons respondToSelector:]:消息发送到已释放实例
【发布时间】:2014-01-27 15:20:20
【问题描述】:

AppCommons.h

#import <Foundation/Foundation.h>
#import <StoreKit/StoreKit.h>

@interface AppCommons : NSObject <SKProductsRequestDelegate,SKRequestDelegate>
- (void) getInAppPrice : (NSString *) inAppIdentifier;
@end

AppCommons.m

#import "Config.h"
#import "AppCommons.h"
#import "AppDelegate.h"
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"


@implementation AppCommons
SKProductsRequest *productsRequest;


- (void) getInAppPrice : (NSString *) inAppIdentifier {
    NSSet *productIdentifiers = [NSSet setWithObject:inAppIdentifier ];
    productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
    productsRequest.delegate = self;
    [productsRequest start];

    // we will release the request object in the delegate callback
}

#pragma mark -
#pragma mark SKProductsRequestDelegate methods

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    for(SKProduct *product in response.products)
    {
        NSLog(@"Product Price : %@",product.price);
                NSLog(@"Product Price Locale : %@",product.priceLocale);
    }
}

@end

这是我获取应用内购买费用的课程。我正在使用以下行从另一个课程调用 getInAppPrice 方法

AppCommons *appCommon = [[AppCommons alloc] init];
[appCommon getInAppPrice:inAppProductIdentifier];

收到响应时出现以下错误

"* -[AppCommons respondToSelector:]: 消息发送到已释放实例 0xd4f0580

请帮忙..谢谢。

【问题讨论】:

  • 不要在方法前面加上get;保留用于非常特定的模式(不是这样)。
  • 您能分享一下它是哪种模式,以便我阅读吗?谢谢。抱歉跑题了。

标签: ios objective-c in-app-purchase


【解决方案1】:

我怀疑你是在方法的范围内这样做的,像这样:

- (void)myMethod {
    AppCommons *appCommon = [[AppCommons alloc] init];
    [appCommon getInAppPrice:inAppProductIdentifier];
}

这意味着appCommon将在方法返回时被销毁。

改为创建一个实例变量或属性,以便AppCommons 对象的生命周期超过此方法调用。

MyClass.h:

@class AppCommons;
@interface MyClass : NSObject {
    AppCommons *_appCommons;
}
...
@end

MyClass.m:

#import "MyClass.h"
#import "AppCommons.h"

@implementation MyClass

- (id)init {
    self = [super init];
    if (self) {
        _appCommons = [[AppCommons alloc] init];
    }
    return self;
}

- (void)myMethod {
    [_appCommons getInAppPrice:inAppProductIdentifier];
}

@end

【讨论】:

  • +1,我加了一点解释,但你绝对是对的。
  • 非常感谢您的解释。它现在工作。 :)
【解决方案2】:

这本身不是答案,而是对错误原因的解释。 trojanfoe给出的答案是绝对正确的,但并不能完全说明情况。

你正在调用一些函数:

- (void)myMethod {
    AppCommons *appCommon = [[AppCommons alloc] init];
    [appCommon getInAppPrice:inAppProductIdentifier];
}

在此函数中,您调用getInAppPrice,它会创建一个新对象并将该新对象的委托设置为您的appCommon。然后该对象在后台等待。

这就是你的问题。当第二个对象在后台等待时,您的appCommon 对象被释放,因为代码到达函数的末尾并释放appCommon。如果您的 SKProductsRequest 委托属性不弱,那么您的 appCommon 的保留计数仍为 1,但由于不是,因此您的 appCommon 在函数结束后保留​​计数为 0,因此 ARC 会看到内存作为可重用并释放对象。

然后您会在后台从您的 SKProductsRequest 对象中获得响应。它检查它的委托指针(指针仍然是一个有效的指针,但它现在指向一个已释放的对象(或更糟糕的是,一个完全不同的对象))以查看它是否响应委托函数。那是对已释放对象的调用。

因此,特洛伊木马将appCommons 对象设为类变量以便在函数结束后对其进行重新调整的答案是正确的答案。保留

【讨论】:

  • 非常感谢您解释情况。
猜你喜欢
  • 2011-06-16
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多