Почему этот сбой? - PullRequest
       15

Почему этот сбой?

0 голосов
/ 19 сентября 2010

Я сделал класс.Это файл h.

//  MyClass.h
#import <Foundation/Foundation.h>


@interface MyClass : NSObject <NSCoding> {
    NSString *string1;
    NSString *string2;

}
@property (nonatomic, retain) NSString *string1;
@property (nonatomic, retain) NSString *string2;

@end

Это файл m.

//  MyClass.m
#import "MyClass.h"


@implementation MyClass
@synthesize string1, string2;

- (void)encodeWithCoder:(NSCoder *)coder;
{
    if (self = [super init]){
        [coder encodeObject:string1 forKey:@"string1"];
        [coder encodeObject:string2 forKey:@"string2"]; 
    }

}

- (id)initWithCoder:(NSCoder *)coder;
{
    self = [[MyClass alloc] init];
    if (self != nil)
    {
        string1 = [coder decodeObjectForKey:@"string1"];
        string2 = [coder decodeObjectForKey:@"string2"];

    }   
    return self;
}

- (void)viewDidUnload {
    self.string1 = nil;
    self.string2 = nil;
}


- (void)dealloc {
    [super dealloc];
    [string1 release];
    [string2 release];
}


@end

Я создал массив этих объектов, например:

MyClass *object1 = [[MyClass alloc] init];
object1.string1 = @"object1 string1";
object1.string2 = @"string1 string2";
MyClass *object2 = [[MyClass alloc] init];
object2.string1 = @"object2 string1";
object2.string2 = @"object2 string2";
theArray = [[NSMutableArray alloc] initWithObjects:object1, object2, nil];

ЗатемЯ сохранил массив следующим образом:

  [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theArray] forKey:@"savedArray"];

Затем я загрузил массив с диска следующим образом.

NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
    NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"savedArray"];
    if (dataRepresentingSavedArray != nil)
    {
        NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
        if (oldSavedArray != nil)
        {
            theArray = [[NSMutableArray alloc] initWithArray:oldSavedArray];
        }
        else {

            theArray = [[NSMutableArray alloc] init];
        }


    }

Программа падает при достижении этой строки в - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

cell.textLabel.text = [[theArray objectAtIndex:indexPath.row] string1];

Почему там происходит сбой?Он не падает, если я не загружаю массив из NSUserDefaults.Тем не менее, я не вижу ничего, что я сделал неправильно с сохранением или загрузкой массива.

Редактировать: я также могу сделать его сбой с этой строкой кода:

NSLog(@"%@", [[theArray objectAtIndex:0] string1]) ;

Ответы [ 4 ]

6 голосов
/ 19 сентября 2010

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

self.string1 = [coder decodeObjectForKey:@"string1"];
self.string2 = [coder decodeObjectForKey:@"string2"];

Чтобы обратиться к первому пункту Коббала, вообще не выполняйте инициализацию в encodeWithCoder:. Просто закодируйте свой объект. Ознакомьтесь с Руководством Apple по программированию архивов и сериализаций для какао для получения более подробной информации о кодировании и декодировании объектов.

3 голосов
/ 19 сентября 2010

Несколько вещей выпрыгивают из меня

  • вы звоните init в encodeWithCoder:.поскольку вы ничего здесь не инициализируете, вам не следует менять self
  • , который вы звоните alloc в initWithCoder:.Когда вы находитесь в методе init, вам не нужно вызывать alloc, просто вызовите self = [super init].
  • , у вас есть метод viewDidUnload.Даже если это было вызвано в подклассе NSObject, вы, вероятно, не хотите избавляться от ваших данных, когда представление выгружено.
  • вы вызываете [super dealloc] в начале вашего метода dealloc.Это должно идти в конце.
1 голос
/ 19 сентября 2010

Я не прочитал весь ваш код, поэтому я не уверен, что это проблема, но в dealloc вы должны вызывать [super dealoc] только после освобождения переменных экземпляра.

0 голосов
/ 19 сентября 2010

Если происходит сбой из-за отсутствия границ, убедитесь, что ваш UITableViewController правильно реализует

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

и

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

для отражения NSArray, который вы используете в качестве источника данных.

...