Начальный квест для программирования iPhone с сохранением / разблокированием / доступом к объекту - PullRequest
1 голос
/ 28 февраля 2010

Я довольно новичок в разработке для iPhone, поэтому, возможно, вы поможете мне с этой проблемой:

У меня есть объект "предпочтения", который содержит одну строку NSString: (Весь код упрощен ...)

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


@interface Preferences : NSObject {
 NSString *username;

}

-(void)loadPreferences;

@property(nonatomic,retain) NSString *username;

@end

Реализация выглядит так:

#import "Preferences.h"
@implementation Preferenes

@synthesize username;

-(void)loadPreferences{
     username=@"MyUser";
}

-(void) dealloc {
 [username release];
}
@end

Далее я использую ссылку сохранения для этого объекта в моем главном делегате:

#import <UIKit/UIKit.h>

@interface MainDelegate : NSObject <UIApplicationDelegate> {

   ...

  Preferences *prefs;
}

@property(retain,nonatomic) Preferences *prefs;

Реализация:

#import "MainDelegate.h"
#import "Preferences.h";

@implementation MainDelegate

@synthesize prefs;

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
     prefs=[[Preferences alloc] init];
     NSLog(@"Username: %@",prefs.username); // THIS WORKS 
}

Так что я могу получить доступ к prefs.username в главном делегате.

Теперь я хочу получить доступ к справке по настройкам из моего основного документа.

Я пытаюсь сделать это так:

MainDelegate *delegate = (MainDelegate*) [[UIApplication sharedApplication] delegate];
Preferences *prefs=delegate.prefs;
// This works...

NSLog(@"The Username is: %@",prefs.username);
// CRASH

Когда я пытаюсь получить доступ к объекту «username» в объекте предпочтений, программа падает, показывая только информацию о лицензии GNU.

Я думаю, что что-то идет не так, что, возможно, объект уже выпущен, когда я пытаюсь получить к нему доступ ...

Можете ли вы помочь мне?

Спасибо!

1 Ответ

2 голосов
/ 28 февраля 2010

У вас могут быть проблемы с назначением вашей собственности. Эта строка не использует ваш установщик свойств, который обрабатывает сохранение значения для вас

username=@"MyUser";

Вы хотите сделать:

self.username = @"MyUser";

Что на самом деле компилируется в

[self setUsername:@"MyUser"];

Вызывает метод, созданный @synthesize username;, который сохраняет эту строку для вас. Так что может случиться так, что вы присваиваете автоматически освобожденную строку для вашей переменной, которая освобождается, и позже вы пытаетесь получить к ней доступ, и она взорвется.

Если вы объявляете свойство с помощью retain, то лучше всего выполнять присваивание и освобождение большую часть времени через это синтезированное свойство. Это значительно упрощает управление памятью.


Эта строка, однако, работает нормально:

prefs=[[Preferences alloc] init];

Это потому, что вы непосредственно устанавливаете переменную экземпляра для объекта с счетом сохранения 1, поскольку он был только инициализирован. Но я обычно предпочитаю использовать установщик свойств, чтобы сделать вещи более ясными и последовательными.

self.prefs = [[[Preferences alloc] init] autorelease];

Это init'ы (+1), они сохраняются установщиком свойств (+1) и позже автоматически высвобождаются (-1). Оставьте счет сохранения 1, который представляет принадлежность объекту делегата приложения.

По моему опыту, использование установщиков сохраненных свойств действительно помогает свести к минимуму ошибки управления памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...