我在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许可证信息。
我认为当我尝试访问它时可能已经释放了一个对象......
你可以帮帮我吗?谢谢!
答案 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委托对象拥有。
根据我的经验,使用保留的属性设置器确实有助于将内存管理错误降至最低。