具有保留/释放/对象访问权限的IPhone编程启动器问题

时间:2010-02-28 19:25:38

标签: objective-c iphone memory-management

我在iPhone开发方面很新,所以也许你可以帮我解决这个问题:

我有一个包含单个NSString的对象“preferences”: (所有代码都简化了......)

#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访问首选项引用。

我试图这样做:

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

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

当我尝试访问首选项对象中的“用户名”对象时,程序崩溃时只显示GNU许可证信息。

我认为当我尝试访问它时可能已经释放了一个对象......

你可以帮帮我吗?

谢谢!

1 个答案:

答案 0 :(得分:2)

您可能在分配财产时遇到问题。此行使用您的属性设置器来处理为您保留值

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,表示由app委托对象拥有。

根据我的经验,使用保留的属性设置器确实有助于将内存管理错误降至最低。