Настройка: У меня есть собственный класс, который я создал, который обрабатывает данные, полученные из веб-источника с помощью ASIHttpRequest. Эти данные в кодировке JSON. В блоке завершения асинхронного запроса пользовательский объект выделяется памяти, а значениям json присваиваются их соответствующие свойства. Этот объект является свойством представления . Внутри блока завершения вызывается метод для настройки представления, и объект передается в headerView, который является подклассом из UIView, а затем устанавливается в tableView.tableHeaderView. На данный момент все работает отлично . UILabels в headerView устанавливаются с использованием свойств пользовательских объектов без помех.
Проблема : В представлении у меня есть UIBarButton, который вызывает метод. Когда вызывается этот метод, и я пытаюсь получить доступ к любому свойству из пользовательского объекта, программа аварийно завершает работу (симулятор iPhone зависает), и xcode указывает на строку, в которой пытается получить доступ свойство, и сообщает «Поток 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
@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;
}