Проблемы с памятью с NSUserDefaults - PullRequest
1 голос
/ 08 июля 2010

Я потратил часы, пытаясь заставить свой проект работать, и я просто не могу заставить его работать.

По сути, я пытаюсь использовать NSUserDefaults для сохранения пользовательского объекта, когда пользователь нажимает кнопку сохранения.и загрузить все данные при загрузке приложения.Если предыдущий NSUserDefault не сохранен, я хочу установить некоторые значения по умолчанию.В конце я получаю EXC_BAD_ACCESS при попытке загрузить ранее сохраненный NSUserDefault.Работает нормально при первой загрузке, при настройке стартовых данных.И дело в том, что когда я пытаюсь включить NSZombieEnabled и другие переменные env для него, он как-то нормально загружается без EXC_BAD_ACCESS.Вот что я работаю:

[App Delegate.h]

#import <UIKit/UIKit.h>
#import "Note.h"

@interface ToDoWallAppDelegate : NSObject <UIApplicationDelegate> {
    ...
    Note *note;
}

...
@property (retain) Note *note;

@end

[App Delegate.m]

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    ...
    note = [[Note alloc] init];

    NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults];
    NSData *noteData = [stdDefaults objectForKey:@"Note"];
    if (noteData) {
        self.note = (Note *)[NSKeyedUnarchiver unarchiveObjectWithData:noteData];
    } else {
        note.background = [UIImage imageNamed:@"Cork.jpg"];
        note.picture = [UIImage imageNamed:@"Cork.jpg"];
        note.font = [UIFont fontWithName:@"Helvetica" size:18.0f];
        note.fontColor = [UIColor blackColor];
        note.fontNameIndex = 9;
        note.fontSizeIndex = 6;
        note.fontColorIndex = 0;
        note.backgroundIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        note.pictureIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        note.text = @"Type note here...";
    }

    ...
}

- (void)dealloc {
    ...
    [note release];
    [super dealloc];
}

[View Controller]

- (void)saveNote {
    ...
    NSUserDefaults *stdDefaults = [NSUserDefaults standardUserDefaults];
    if (stdDefaults) {
        NSData *noteData = [NSKeyedArchiver archivedDataWithRootObject:UIAppDelegate.note];
        [stdDefaults setObject:noteData forKey:@"Note"];
        [stdDefaults synchronize];
    }
}

[Note.h]

#import <Foundation/Foundation.h>


@interface Note : NSObject <NSCoding> {
    UIImage *background, *picture;
    UIFont *font;
    UIColor *fontColor;
    int fontNameIndex, fontSizeIndex, fontColorIndex;
    NSIndexPath *backgroundIndexPath, *pictureIndexPath;
    BOOL customBackground;
    NSString *text;
}

@property (retain) UIImage *background, *picture;
@property (retain) UIFont *font;
@property (retain) UIColor *fontColor;
@property int fontNameIndex, fontSizeIndex, fontColorIndex;
@property (retain) NSIndexPath *backgroundIndexPath, *pictureIndexPath;
@property BOOL customBackground;
@property (retain) NSString *text;

- (Note *)init;

@end

[Note.m]

#import "Note.h"


@implementation Note

@synthesize background, picture, font, fontColor, fontNameIndex, fontSizeIndex, fontColorIndex, customBackground, backgroundIndexPath, pictureIndexPath, text;

- (Note *)init {
    if (self = [super init]) {
        background = [[UIImage alloc] init];
        picture = [[UIImage alloc] init];
        font = [[UIFont alloc] init];
        fontColor = [[UIColor alloc] init];
        backgroundIndexPath = [[NSIndexPath alloc] init];
        pictureIndexPath = [[NSIndexPath alloc] init];
        text = [[NSString alloc] init];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)encoder {
    NSData *dataBackground = UIImagePNGRepresentation(background);
    NSData *dataPicture = UIImagePNGRepresentation(picture);

    [encoder encodeObject:dataBackground forKey:@"dataBackground"];
    [encoder encodeObject:dataPicture forKey:@"dataPicture"];
    [encoder encodeObject:font forKey:@"font"];
    [encoder encodeObject:fontColor forKey:@"fontColor"];
    [encoder encodeInt:fontSizeIndex forKey:@"fontSizeIndex"];
    [encoder encodeInt:fontColorIndex forKey:@"fontColorIndex"];
    [encoder encodeBool:customBackground forKey:@"customBackground"];
    [encoder encodeObject:backgroundIndexPath forKey:@"backgroundIndexPath"];
    [encoder encodeObject:pictureIndexPath forKey:@"pictureIndexPath"];
    [encoder encodeObject:text forKey:@"text"];
}

- (Note *)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        NSData *dataBackground = [decoder decodeObjectForKey:@"dataBackground"];
        NSData *dataPicture = [decoder decodeObjectForKey:@"dataPicture"];
        background = [[UIImage imageWithData:dataBackground] retain];
        picture = [[UIImage imageWithData:dataPicture] retain];
        font = [[decoder decodeObjectForKey:@"font"] retain];
        fontColor = [[decoder decodeObjectForKey:@"fontColor"] retain];
        fontNameIndex = [decoder decodeIntForKey:@"fontNameIndex"];
        fontColorIndex = [decoder decodeIntForKey:@"fontColorIndex"];
        customBackground = [decoder decodeBoolForKey:@"customBackground"];


    backgroundIndexPath = [[decoder decodeObjectForKey:@"backgroundIndexPath"] retain];
        text = [[decoder decodeObjectForKey:@"text"] retain];
    }
    return self;
}

- (void)dealloc {
    [super dealloc];
    [background release];
    [picture release];
    [font release];
    [fontColor release];
    [backgroundIndexPath release];
    [pictureIndexPath release];
    [text release];
}

@end

Мне действительно нужна помощь, я ценю это.

Редактировать:

Кстати, есть также строки из других файлов, которые редактируютобъект Note делегата приложения, такой как:

#define UIAppDelegate ((ToDoWallAppDelegate *)[UIApplication sharedApplication].delegate)
...
UIAppDelegate.note.backgroundIndexPath = indexPath;

Редактировать:

Вот что написал отладчик:

#0  0x90be9ed7 in objc_msgSend
#1  0x03b05210 in ??
#2  0x000023ce in -[ToDoWallAppDelegate setNote:] at ToDoWallAppDelegate.m:14
#3  0x00002216 in -[ToDoWallAppDelegate applicationDidFinishLaunching:] at ToDoWallAppDelegate.m:35

Которые являются:

note.text = @"Type note here...";
//and
@synthesize window, note;

Ответы [ 2 ]

7 голосов
/ 08 июля 2010

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

1 голос
/ 08 июля 2010

Ознакомьтесь с документацией по настройке значений по умолчанию Использование NSUserDefaults

Если вам нужна дополнительная информация, загляните в книгу Хиллегы "Программирование какао для Mac OS X" bignerdranch.com/books, это объясняется там.

Вы должны рассмотреть вопрос об изменении заголовка на "Как использовать NSUserDefaults" ...

Пример, как установить значение по умолчанию, в вашем классе в initialize поставить что-то вроде:

+ (void)initialize{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *appDefaults = [NSDictionary
        dictionaryWithObject:@"YES" forKey:@"DeleteBackup"];

    [defaults registerDefaults:appDefaults];
}

Вы можете публиковать, где именно вы получаете сообщение об ошибке, вместо того, чтобы публиковать весь код.Запустите его через отладчик и посмотрите, где он останавливается.

...