【问题标题】:Debugging a EXC_BAD_ACCESS - Objective-C - Xcode 8.0调试 EXC_BAD_ACCESS - Objective-C - Xcode 8.0
【发布时间】:2017-03-16 13:12:53
【问题描述】:

我是 Objective-c 领域的新手,我遇到了 EXC_BAD_ACCESS。我知道 stackoverflow 上有很多论坛和相关内容 - 但是我仍然无法找到崩溃的根源。

我有游戏代码,当我退出关卡和租用者时 - 应用程序崩溃。以下是我竞相尝试并定位崩溃源和显示内容的步骤:

图 1:

以下是相关的消息:

图 2:

图 3:

图 4:

图 5:

图 6:

我已启用 NSZombies 并在应用崩溃时获取此日志:

Journey[76657:4493989] *** -[UILabel isKindOfClass:]: message sent to deallocated instance 0x60030b4d0d80. 

我已经查过这种类型的错误,但我仍然不确定如何阅读它。接下来我尝试了:

(lldb) command script import lldb.macosx.heap
"malloc_info", "ptr_refs", "cstr_refs", "find_variable", and "objc_refs" commands have been installed, use the "--help" options on these commands for detailed help.
(lldb) malloc_info --stack-history 0x60030b4d0d80

我读到这将帮助我确定我的代码中可能发生崩溃的确切行,但输出似乎与我的代码中的不匹配:

2016-11-02 19:47:47.338190 Casino Journey[76657:4498737] [] nw_socket_handle_socket_event Event mask: 0x4
2016-11-02 19:47:47.339741 Casino Journey[76657:4494204] [] tcp_connection_cancel 17
2016-11-02 19:47:47.346972 Casino Journey[76657:4498737] [] nw_socket_handle_socket_event Socket received WRITE_CLOSE event
2016-11-02 19:47:47.351492 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17 live.chartboost.com:443 ready resolver (satisfied)]
2016-11-02 19:47:47.358787 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.1 54.236.125.98:443 ready socket-flow (satisfied)]
2016-11-02 19:47:47.366406 Casino Journey[76657:4498737] [] __nw_socket_service_writes_block_invoke sendmsg(fd 13, 31 bytes): socket has been closed
2016-11-02 19:47:47.370392 Casino Journey[76657:4498737] [] nw_endpoint_flow_protocol_error [17.1 54.236.125.98:443 cancelled socket-flow (null)] Socket protocol sent error: [32] Broken pipe
2016-11-02 19:47:47.373586 Casino Journey[76657:4498737] [] nw_endpoint_flow_protocol_disconnected [17.1 54.236.125.98:443 cancelled socket-flow (null)] Output protocol disconnected
2016-11-02 19:47:47.376552 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.2 107.23.51.227:443 initial path (null)]
2016-11-02 19:47:47.380708 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.3 54.85.200.4:443 initial path (null)]
2016-11-02 19:47:47.383242 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.4 54.86.68.178:443 initial path (null)]
2016-11-02 19:47:47.385251 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.5 54.85.112.211:443 initial path (null)]
2016-11-02 19:47:47.387182 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.6 107.23.150.89:443 initial path (null)]
2016-11-02 19:47:47.388414 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.7 107.21.6.246:443 initial path (null)]
2016-11-02 19:47:47.389678 Casino Journey[76657:4498737] [] nw_endpoint_handler_cancel [17.8 54.210.97.43:443 initial path (null)]
2016-11-02 19:47:47.394671 Casino Journey[76657:4498737] [] nw_resolver_cancel_on_queue 0x6005eb89df70
2016-11-02 19:47:47.399258 Casino Journey[76657:4498737] [] -[NWConcrete_tcp_connection dealloc] 17
GuardMalloc[Casino Journey-76657]: Attempting excessively large memory allocation:  268435456 bytes
GuardMalloc[Casino Journey-76657]: If you really wanted to allocate so much memory, launch your executable with the environment variable MALLOC_PERMIT_INSANE_REQUESTS set to any value to circumvent this check.
GuardMalloc[Casino Journey-76657]: Explicitly trapping into debugger!!!
0x000060030b4d0d80: malloc(   640) -> 0x60030b4d0d80 _NSZombie_UILabel
error: expression failed "
typedef int kern_return_t;
typedef unsigned task_t;
#define MAX_FRAMES 128
#define MAX_HISTORY 16
typedef struct mach_stack_logging_record_t {
    uint32_t type_flags;
    uint64_t stack_identifier;
    uint64_t argument;
    uint64_t address;
} mach_stack_logging_record_t;
typedef void (*enumerate_callback_t)(mach_stack_logging_record_t, void *);
typedef struct malloc_stack_entry {
    uint64_t address;
    uint64_t argument;
    uint32_t type_flags;
    uint32_t num_frames;
    uint64_t frames[MAX_FRAMES];
    kern_return_t frames_err;    
} malloc_stack_entry;
typedef struct $malloc_stack_history {
    task_t task;
    unsigned idx;
    malloc_stack_entry entries[MAX_HISTORY];
} $malloc_stack_history;
$malloc_stack_history info = { (task_t)mach_task_self(), 0 };
uint32_t max_stack_frames = MAX_FRAMES;
enumerate_callback_t callback = [] (mach_stack_logging_record_t stack_record, void *baton) -> void {
    $malloc_stack_history *info = ($malloc_stack_history *)baton;
    if (info->idx < MAX_HISTORY) {
        malloc_stack_entry *stack_entry = &(info->entries[info->idx]);
        stack_entry->address = stack_record.address;
        stack_entry->type_flags = stack_record.type_flags;
        stack_entry->argument = stack_record.argument;
        stack_entry->num_frames = 0;
        stack_entry->frames[0] = 0;
        stack_entry->frames_err = (kern_return_t)__mach_stack_logging_frames_for_uniqued_stack (
            info->task, 
            stack_record.stack_identifier,
            stack_entry->frames,
            (uint32_t)MAX_FRAMES,
            &stack_entry->num_frames);
        // Terminate the frames with zero if there is room
        if (stack_entry->num_frames < MAX_FRAMES)
            stack_entry->frames[stack_entry->num_frames] = 0; 
    }
    ++info->idx;
};
(kern_return_t)__mach_stack_logging_enumerate_records (info.task, (uint64_t)0x60030b4d0d80, callback, &info);
info" => error: error: Execution was interrupted, reason: EXC_BREAKPOINT (code=EXC_I386_BPT, subcode=0x0).
The process has been returned to the state before expression evaluation.

如果有人可以帮助我确定此错误的可能来源,我将不胜感激!尝试调试此类错误时的一般帮助或 cmets。

我也在使用最新版本的 xcode:8.0 版

编辑: 我正在添加 BaseViewController 的代码 - 我知道这可能很难阅读并且很复杂,有很多文件包含实际代码:

//
//
//

#import <UIKit/UIKit.h>
#import <StoreKit/StoreKit.h>
#import "PHPublisherContentRequest.h"
#import <Foundation/Foundation.h>
#import "PHAPIRequest.h"
#import "PHContentView.h"
#import "AppController.h"
#import "Define.h"

@interface BaseViewController : UIViewController <SKProductsRequestDelegate, SKPaymentTransactionObserver, PHAPIRequestDelegate, PHPublisherContentRequestDelegate> {

    IBOutlet UIActivityIndicatorView *activityIndicator;
    BaseViewController *superClassDelegate;
}

- (void)exitIAP;
-(void) buyProductWithIdentifier:(NSString *) productIdentifier;
-(void) sendVgpCallToPlayHavenForPlacement:(NSString *) placementTag;


@end

【问题讨论】:

  • 在第二张图片中,将发布移动到顶部,然后将其设置为nil。你能显示BaseViewController 头文件吗?代码很难看懂。
  • 感谢您的评论 - 我确实理解代码有点难以阅读 - 我添加了 BaseViewController 的内容 - 所以您的建议是将 dealloc 移动到顶部然后设置发给nil? - 如果有帮助,我也可以发送代码。
  • dealloc 必须是最后一个呼叫。在将其设置为nil 之前,您需要移动release 方法调用,然后调用dealloc。同时需要释放superClassDelegate,这是不合适的。您需要检查如何定义delegate

标签: ios objective-c iphone xcode memory-management


【解决方案1】:

请检查以下事项:-

  1. 转到目标
  2. 选择构建阶段
  3. 选择编译源
  4. 选择您的文件/类名
  5. 双击编译器标志

在框中输入一个字-fno-objc-arc

在输入-fno-objc-arc 后清理并构建您的应用程序。

【讨论】:

    【解决方案2】:

    正如@New16 所说,变量应该在设置为零之前释放。

    如果我是你,我会在你的 BaseViewController 中查看 UILabel

    【讨论】:

      【解决方案3】:

      我是 Objective-c 领域的新手

      欢迎来到 Objective-C。这是您将获得的最佳建议:

      使用弧线!!!

      真的。编译器比你更了解内存管理。使用 ARC 并失去所有这些保留、释放和释放。现在就做吧。

      【讨论】:

      • 更好的是,直接跳过 Objective-C 并学习 Swift。但我并不坚持这一点。你想坚持使用Objective-C,很好,无论如何。但我坚持你使用 ARC。
      猜你喜欢
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      相关资源
      最近更新 更多