Как можно решить ошибку «SIGKILL» в UITableView (при построении представления таблицы с использованием раскадровки) - PullRequest
1 голос
/ 04 марта 2012

Я новичок в разработке IOS. Я пытаюсь использовать раскадровку для создания UITableView, но когда я запускаю это приложение, появляется сообщение «Программа получила сигнал:« SIGKILL »».

Я создал таблицу с использованием раскадровки (без ARC), но во время выполнения возникла проблема. Здесь дано в коде:


#import "MainTableViewController.h"
@interface MainTableViewController ()
@property (strong, nonatomic) NSMutableArray *myArray;
@end

@implementation MainTableViewController
@synthesize myArray;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
// Custom initialization
    }
return self;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

#pragma mark - View lifecycle
- (void)viewDidLoad
{
    [super viewDidLoad];
myArray = [NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    self.myArray = nil;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [myArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
    cell.textLabel.text = [myArray objectAtIndex:indexPath.row]; // 这儿出现异常 Program received signal:  “SIGKILL”
    return cell;
}

#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{ }
@end

enter image description here

Я двигаюсь вверх и вниз по экрану, а затем возникает эта ошибка во время выполнения. Я включил функцию зомби. Я обнаружил, что myArray - NSZombie Objects,

А затем отладка продолжается, и я обнаружил еще одну ошибку "EXC_BAD_ACCESS" в той же строке. cell.textLabel.text = [myArray objectAtIndex: indexPath.row]; MyArray по-прежнему является объектом зомби.

Как вы решаете это? Спасибо! !

1 Ответ

3 голосов
/ 04 марта 2012

Вы создали myArray, используя метод arrayWithObjects:. Этот метод возвращает объект, которым вы не владеете. Так как он вам не принадлежит, объект может быть освобожден (превращен в зомби) в следующий раз, когда программа пройдет цикл выполнения. На самом деле, это именно то, что происходит.

Если вы хотите, чтобы объект оставался рядом, вы должны стать его владельцем. Вы делаете это, сохраняя это. Есть три способа сохранить его. Вы можете явно отправить ему сообщение retain:

myArray = [[NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil] retain];

или вы можете использовать метод установки свойств:

[self setMyArray:[NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil]];

Вы можете использовать точечный синтаксис, который использует метод установки свойств «под прикрытием»:

self.myArray = [NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil];

Метод установки свойств (генерируемый компилятором) автоматически сохраняет объект.

Вы помещаете ссылку непосредственно в переменную вашего экземпляра, а не используете метод setter. Легко сделать эту ошибку. Компилятор может помочь вам поймать эту ошибку, если вы синтезируете свое свойство по-другому:

@synthesize myArray = _myArray;

Если вы сделаете это, свойство будет сохранено в переменной экземпляра с именем _myArray вместо переменной экземпляра с именем myArray. Поэтому вы должны явно использовать _ перед именем для прямого доступа к переменной экземпляра:

// COMPILE-TIME ERROR!
myArray = [NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil];

// Compiles ok
_myArray = [[NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil] retain];

// Also compiles ok
self.myArray = [NSMutableArray arrayWithObjects:@"apple",@"orange",@"bananas", nil];

Если вы используете префикс _ во всех переменных вашего экземпляра, то вы знаете, что всякий раз, когда вы устанавливаете что-то, начинающееся с _, вам нужно беспокоиться о сохранении нового значения и освобождении старого значения.

третий способ сохранить объект, и лучше всего включить ARC (автоматический подсчет ссылок) для вашего проекта. Тогда вам не нужно беспокоиться о сохранении и освобождении объектов. Компилятор автоматически сохранит и освободит объект в нужное время, даже если вы используете переменную экземпляра напрямую.

Если вы решите не использовать ARC, тогда вам понадобится для изучения Компетенции Cocoa Core : «Управление памятью» , до Вы понимаете правила.

...