苹果内购内存错误调试

苹果规定,虚拟商品必须采用内购形式购买。

在接入内购过程中,遇到一个内存泄漏问题。如下图,

具体操作方式:点击获取商品列表页面,在商品列表没有加载完毕时,返回上一级页面,此时闪退。报错如上图。

解决方式:

分析:在此引入僵尸对象概念,所谓僵尸对象,是用于捕捉内存错误的调试功能。

通常情况下,当引用计数降为0时对象会立即被释放,但这使调试变得困难。如果开启了僵尸对象,那么对象就不会立即释放内存,而是被标记为僵尸。任何试图对其进行访问的行为都会被日志记录,因而你可以在对象的生命周期中跟踪对象在代码中被使用的位置。

NSZombieEnabled是一个环境变量,可以控制Core Foundation的运行时是否将使用僵尸对象。不应长期保留NSZombieEnabled,因为默认情况下是不会有对象被真正析构,这会导致应用使用大量的内存。特别说明:在发布的构建包中一定要禁用NSZombieEnabled。

设置NSZombieEnabled环境变量,需要进入Product->Scheme->Edit Scheme。选择左侧的Run,然后再右侧选取Diagnostics标签页。选中Enable Zombie Objects 选项。

设置完成后,报错如下:

通过日志可以清晰地确认是哪个类发生了内存泄漏。于是,追踪到这个类,发现注册的通知,在最后dealloc中已经移除了。同时根据断点,发现在返回上一级后,代理的方法,还在执行。故而想到试着把代理置为nil。

因而最终解决方式是:

SKProductsRequest *request;

- (void)dealloc {

    [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];

    request.delegate = nil;

}

注:在进行必要清理时一定要移除观察者(具体来说,移除对通知的注册),解除回调(具体来说,将强引用的委托设置为nil)。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • iOS内存管理 概述 什么是内存管理 应用程序内存管理是在程序运行时分配内存(比如创建一个对象,会增加内存占用)与...
    蚊香酱阅读 5,782评论 8 119
  • 29.理解引用计数 Objective-C语言使用引用计数来管理内存,也就是说,每个对象都有个可以递增或递减的计数...
    Code_Ninja阅读 1,583评论 1 3
  • 内存管理 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与a...
    丶逐渐阅读 2,032评论 1 16
  • 先来一发苹果官网上Instruments User Guide,其实没啥用,英语不好的也懒得去看。(反正我是看不懂...
    和珏猫阅读 30,251评论 51 376
  • 如果生活没法选择光明 那么让他不屈的灵魂照亮我 我不怕做扑火的飞蛾 会和他一起唱属于遥远的歌 做清醒的梦 成为勇敢的少年
    迟迟不会晚阅读 183评论 0 0