Objective c objective c中的单例对象内存问题
我在这个问题上已经坚持了一段时间,任何建议都将不胜感激。我创建了一个名为SharedUser的单例对象,它表示当前正在使用该应用程序的用户。此SharedUser对象有两个NSString(用于用户名和用户ID)和一个NSArray(用于用户所属的公司部门)。用户在登录时使用名为initWithUsername的方法初始化。在该方法中,用户名用于解析用户并获取用户的唯一id号和用户的部门 我的问题如下:当我稍后在应用程序中通过sharedUser方法获取用户时,userId字符串为空,并在我尝试使用它时导致exc_bad_访问错误。我知道userId字符串正在初始化,因为我在调试器中观察到了这种情况。然而,奇怪的是,对于缺少userId字符串的同一对象,username字符串仍然存在。我很困惑userId背后的内存是如何被释放的,而username仍然挂着 我的SharedUser类如下所示:Objective c objective c中的单例对象内存问题,objective-c,cocoa-touch,memory-management,singleton,exc-bad-access,Objective C,Cocoa Touch,Memory Management,Singleton,Exc Bad Access,我在这个问题上已经坚持了一段时间,任何建议都将不胜感激。我创建了一个名为SharedUser的单例对象,它表示当前正在使用该应用程序的用户。此SharedUser对象有两个NSString(用于用户名和用户ID)和一个NSArray(用于用户所属的公司部门)。用户在登录时使用名为initWithUsername的方法初始化。在该方法中,用户名用于解析用户并获取用户的唯一id号和用户的部门 我的问题如下:当我稍后在应用程序中通过sharedUser方法获取用户时,userId字符串为空,并在我尝试
@implementation SharedUser
@synthesize userId;
@synthesize username;
@synthesize departmentIds;
static SharedUser *sharedUser = nil;
+(SharedUser *)sharedUser {
@synchronized(self) {
if (!sharedUser) {
sharedUser=[[self alloc] init];
}
}
return sharedUser;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedUser == nil) {
sharedUser = [super allocWithZone:zone];
return sharedUser;
}
}
return nil;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return NSUIntegerMax;
}
- (oneway void)release {
// never release
}
- (id)autorelease {
//do nothing
}
- (id) init {
@synchronized(self) {
[super init];
username = @"";
userId = @"";
departmentIds = nil;
return self;
}
}
- (void) initWithUserName:(NSString *) loginName {
username = loginName;
//create a request and a connection
NSURL *url = [NSURL URLWithString:@"http://blah.com/url/for/the/json/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *responseString = [request responseString];
NSArray *listOfPeopleDictionaries = [responseString JSONValue];
for (NSDictionary *personDictionary in listOfPeopleDictionaries) {
if ([loginName isEqualToString:[personDictionary objectForKey:@"username"]]) {
// Set the user id
userId = [personDictionary objectForKey:@"id"];
// Set the user's department
NSArray *departmentsArray = [personDictionary objectForKey:@"organizations"];
for (NSDictionary *department in departmentsArray) {
[departmentIds addObject:[department objectForKey:@"id"]];
}
}
}
}
else {
//give error
}
}
- (void)dealloc {
// Should never be called
[username release];
[userId release];
[departmentIds release];
[super dealloc];
}
以下代码将导致第三行出现exc_bad_访问错误
SharedUser *user = [SharedUser sharedUser];
NSLog(@"%@", user.username);
NSLog(@"%@", user.userId);
这就是说,我的问题是,释放userId字符串背后的内存在哪里?我该如何修复它?我是stack overflow的新手,所以请温柔一点。
userId
不会被您的单身汉保留。该值归personDictionary
所有,该值归ListofPeopleDictionary
所有,它是从[responseString JSONValue]
自动返回的返回值。当自动释放池被清除时,整个链被释放,包括userId
解决方案是保留userId,或者
userId = [[personDictionary objectForKey:@"id"] retain];
或
username
也有同样的问题,但当您在调用initWithUserName:
的对象中保留它时,它可能不会崩溃。我可能会使用另一个解决方案:“normal”类,它提供一个共享实例,而它不需要考虑所有的内存(非)管理
我想提出新的中央大调度方法
@implementation User
@synthesize userId;
@synthesize username;
@synthesize departmentIds;
+ (User *)sharedUser {
static User *_sharedUser = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedUser = [[self alloc] init…];
//what ever is needed to get a proper shared user
});
return _sharedUser;
}
@end
如果您对不太严格的单例版本满意,则不需要更多
这在单元测试中也更容易处理
User *sharedUser = [User sharedUser];
若要修复代码,请重试
username = [loginName copy]; //or retain, if you use retain in ur property
而不是
username = loginName;
共享用户…听起来很有趣-就像一个开放的关系…
username = loginName;