Странное поведение одноэлементного объекта - PullRequest
0 голосов
/ 12 января 2012

У меня действительно странная ситуация. Я создаю одиночный объект класса с именем «Профиль» следующим образом:

static Profile *currentProfile;

+ (Profile *)currentProfile
{
@synchronized(self)
{
    if (currentProfile == nil)
        currentProfile = [[Profile alloc] init];
}

return currentProfile;
}

- (id)init
{
self = [super init];
if (self)
 {
    // Initialization code here.
    isChecked = [[[NSUserDefaults standardUserDefaults] objectForKey:@"isChecked"] boolValue];       

     if (isChecked)
     {
         NSLog(@"isChecked block is called");
         NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myEncodedObjectKey"];
         self         = (Profile *) [NSKeyedUnarchiver unarchiveObjectWithData:data];
         [self retain];

         for (int i = 0; i < self.avatar.count; i++)
             [self.avatar replaceObjectAtIndex:i withObject:[UIImage imageWithData:[self.avatar objectAtIndex:i]]]; 
     }

     else
     {
         password  = @""; 
         pfefferID = @"";
         email     = @"";
         avatar    = [[NSMutableArray alloc] initWithObjects:
                     [UIImage imageNamed:@"empty_image.png"], 
                     [UIImage imageNamed:@"empty_image.png"],
                     [UIImage imageNamed:@"empty_image.png"],
                     [UIImage imageNamed:@"empty_image.png"],
                     [UIImage imageNamed:@"empty_image.png"],nil];
         isBoy     = YES;
         friends   = [[NSMutableDictionary alloc] init]; 
         rating    = 0; 
     }
  }

return self;
}

В методе init я проверяю определенное условие, хранящееся в NSUserDefaults, используя переменную BOOL с именем isChecked. isChecked равен YES, и все работает нормально. Но ... я создаю этот объект профиля в файле AppDelegate, как это

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
users                         = [[NSMutableDictionary alloc] init];
usersForLeaderboardFromServer = [[NSMutableDictionary alloc] init];
listOfFriendsFromServer       = [[NSMutableDictionary alloc] init];
currentProfile                = [Profile currentProfile];
sessionID                     = 0;

if (!currentProfile.isChecked)//why????
    NSLog(@"not checked");

if (currentProfile.isChecked)
{
    [self getUsersForLeaderboardFromServer];

    MainMenuView *mainMenu = [[[MainMenuView alloc] init] autorelease];
    [self.navigationController pushViewController:mainMenu animated:YES]; 
}
}

Таким образом, та же самая переменная isChecked, которая моментом (намного меньше, чем момент фактически) назад была равна YES, становится равной NO при использовании в методе didFinishLaunchingWithOptions приложения, получая к нему доступ через точку. В чем дело? Я могу справиться с этим, но мне просто любопытно, в этой ситуации. Вы знаете, что с ним не так?

1 Ответ

2 голосов
/ 12 января 2012

Вы переназначаете self в init, поэтому вы возвращаете новый объект, а не тот, который вы установили isChecked.См. Этот код:

self         = (Profile *) [NSKeyedUnarchiver unarchiveObjectWithData:data];
[self retain];

Немного неловко делать такие вещи, которые есть у вас - я бы, конечно, не рекомендовал заменять их так, как вы.Для начала, значение, которое вы установили для статического currentProfile, не обновляется при переназначении self, так что оно все еще старое.И также вы не выпускаете старый self при переназначении.

Чтобы исправить это, вы можете сделать что-то вроде этого:

id newSelf         = (Profile *) [NSKeyedUnarchiver unarchiveObjectWithData:data];
newSelf.isChecked = isChecked;
[self release];
self = [newSelf retain];

Но я на самом деле не защищаю это лично,Я предлагаю вам загрузить объект из вашего архива, а затем приступить к обновлению себя с ним, а не переназначать себя.

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