【发布时间】:2017-03-16 13:12:53
【问题描述】:
我是 Objective-c 领域的新手,我遇到了 EXC_BAD_ACCESS。我知道 stackoverflow 上有很多论坛和相关内容 - 但是我仍然无法找到崩溃的根源。
我有游戏代码,当我退出关卡和租用者时 - 应用程序崩溃。以下是我竞相尝试并定位崩溃源和显示内容的步骤:
以下是相关的消息:
我已启用 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