对象属性在某些方法中抛出未知错误

时间:2011-06-16 13:55:58

标签: iphone objective-c cocoa-touch asihttprequest

设置:我创建了一个自定义类,它使用ASIHttpRequest处理从Web源检索的数据。该数据是json编码的。在异步请求的完成块中,将自定义对象分配给内存,并将json值设置为其对应的属性。 此对象是视图的属性。在完成块中,调用设置视图的方法,并将对象传递到headerView,该headerView是从UIView继承的,然后设置为tableView.tableHeaderView。在这一点上,一切都完美。 headerView中的UILabels使用自定义对象属性设置,没有任何障碍。

问题:在视图中,我有一个调用方法的UIBarButton。调用此方法并尝试从自定义对象访问任何属性时,程序崩溃(iPhone模拟器冻结),xcode指向尝试访问该属性的行,并显示“Thread 1”。调试器中没有任何错误。当我NSLog自定义对象时,返回的内存地址与我访问它时没有任何问题的地址相匹配。

有什么想法吗?他们的任何调试方法都有助于解决这个问题吗?我不明白为什么视图的一个方法访问这些属性没有任何问题,另一个方法会。感谢。

编辑:我禁用了僵尸,现在收到EXC_BAD_ACCESS错误,而不是没有错误。

修改代码

@class Obj, ObjHeader;
@interface ObjTableViewController : UITableViewController <UIActionSheetDelegate> {

@public
    NSString* objID;
@private
    Obj* obj;
    ObjHeader* headerView;
}
@property (nonatomic, retain) NSString* objID;
@property (nonatomic, retain) Obj* obj;

@property (nonatomic, retain) ObjHeader* headerView;

- (void)loadObj; // Loads Obj via async request
- (void)setupView; // This method runs after a async request is successful 

- (void)viewDidLoad
{   
    [self loadObj];
    [super viewDidLoad];
}

- (void)loadObj {
    // Start request
    ASIFormDataRequest* request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:OBJ_URL]];
    [request setPostValue:self.objID forKey:@"ObjID"];

    // Successful request
    [request setCompletionBlock:^{
        self.obj = [[Obj alloc] initWithString:[request responseString]];
        [self setupView];
    }];

    [request setFailedBlock:^{
        NSError *error = [request error];
        NSLog(@"Error on obj request with error %@",[error localizedDescription]);
    }];

    [request startAsynchronous];
}

    - (void)setupView {
        // Header setup
        self.headerView = [[ObjHeader alloc] initWithObj:self.obj];
        self.tableView.tableHeaderView = self.headerView;



        // Title 
        self.title = self.obj.name; // SUCCESSFUL ACCESS HERE
        UIBarButtonItem* optsButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction 
                                                                                     target:self 
                                                                                     action:@selector(showOpts:)] 
                                       autorelease];

        self.navigationItem.rightBarButtonItem = optsButton;

    }
- (void)showOpts:(id)sender {
    NSLog(@"%@",self.obj.name); // EXC_BAD_ACCES 
}

Obj Class

@interface Obj : NSObject {

@public
    NSString* name;
}

@property (nonatomic, readonly, retain) NSString* name;
- (id)initWithString:(NSString*)responseString;

- (id)initWithString:(NSString*)responseString {
    self = [super init];
    if(self) {
        NSArray* json = [[NSString stringWithString:responseString] JSONValue];
        name    = [json valueForKeyPath:@"Obj.Name"];
    } // END IF
    return self;
}

ObjHeader类 - 我很确定这是无关紧要的,因为当我不使用它时问题仍然存在! :P

@class Obj;
@interface ObjHeader : UIView {

@public
    UILabel* nameLabel;
}
@property (nonatomic, readonly, retain) UILabel* nameLabel;

- (id)initWithObj:(Obj*)obj;


- (id)initWithObj:(Obj*)obj
{
    CGRect frame = CGRectMake(0, 0, 320.0f, 480.0f / 4.0);
    self = [super initWithFrame:frame];
    if (self) {

        const CGFloat labelWidth = 320.0f - 15.0f;

        // Setup Name label
        const CGFloat nameFontSize = 17.0f;
        CGRect nameFrame = CGRectMake( 70.0f, 10.0f, 
                                      labelWidth, nameFontSize);
        nameLabel = [[UILabel alloc] initWithFrame:nameFrame];
        nameLabel.text = obj.name;
        nameLabel.font = [UIFont fontWithName:SYSFONT size:nameFontSize];
        [self addSubview:nameLabel];
    }
    return self;
}

2 个答案:

答案 0 :(得分:1)

我认为这里存在问题:

 name    = [json valueForKeyPath:@"Obj.Name"];

这是一个自动释放的对象,因此您需要在开头使用self.name或在结尾处保留。

答案 1 :(得分:0)

这可能是无限循环的问题。检查您是否具有相同的方法名称和实例var?就像你声明一个名为myValue的实例var并创建一个名为

的方法一样
- (void)setMyValue;

检查是否是这种情况或无限循环。