2014-08-30 1 views
0

У меня есть класс в моем приложении, который представляет пользователя, OtherUser. Этот класс содержит несколько объектов NSString *. Когда я присваиваю эти свойства статическим строкам @"string", свойства сохраняются как значения __NSCFConstantString *. Когда я назначаю их строками, преобразованными из JSON, они сохраняются как значения __NSCFString *. Я сохраняю изменяемый массив изменяемых массивов объектов OtherUser. Когда я обращаюсь к массиву вне функции, в которой назначены значения, сохраняются только значения __NSCFConstantString *, а значения __NSCFString * - все равно. Есть ли способ конвертировать объекты NSCFString в объекты NSCFConstantString или каким-то образом обойти это ограничение?__NSCFString в NSMutableArray становится nil вне функции, где назначается

This - это то, что массив выглядит, как только его значения были назначены в моем методе ConnectionDidFinishLoading. Пользователь Test Testman был создан с загруженными данными JSON, а пользователь Rose Lalonde был создан локально с @"string" значениями.

This - это то, что выглядит массив, когда я подтягиваю его снова в своем методе CellForRowAtIndexPath. Test Testman теряет все свои данные, за исключением своего идентификатора, в то время как Роза Лалонде сохраняет все свои. (Приносим извинения за привязку изображений вместо встраивания - моя репутация недостаточно высока, чтобы вставлять изображения еще).

Вот мой метод connectionDidFinishLoading, который называется первым и создает массивы:

//Called when the connection finishes loading all data 
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    NSLog(@"Connection finished!"); 

    //Converts downloaded JSON data to an array 
    NSError *error = [[NSError alloc] init]; 
    NSArray *arr = [NSJSONSerialization JSONObjectWithData:_responseData 
                options:kNilOptions 
                error:&error]; 

    //Checks if the array was properly instantiated 
    if (!arr) { 
     NSLog(@"Error parsing JSON: %@", error); 
    } else { 
     //Initializes the arrays if they are not already initialized 
     if (!_bestFriends) _bestFriends = [[NSMutableArray alloc] init]; 
     if (!_onlineFriends) _onlineFriends = [[NSMutableArray alloc] init]; 
     if (!_offlineFriends) _offlineFriends = [[NSMutableArray alloc] init]; 

     //Loops through each result dictionary and creates a friend object with its contents 
     for(NSDictionary *item in arr) { 
      OtherUser *friend = [[OtherUser alloc] init]; 
      friend.firstname = [NSString stringWithString:(NSString *)[item objectForKey:@"firstname"]]; 
      friend.lastname = (NSString *)[item objectForKey:@"lastname"]; 
      friend.username = (NSString *)[item objectForKey:@"username"]; 
      friend.userID = [NSNumber numberWithInt:[(NSString *)[item objectForKey:@"userID"] intValue]]; 
      friend.isOnline = [(NSString *)[item objectForKey:@"isOnline"] boolValue]; 
      friend.isInSession = [(NSString *)[item objectForKey:@"isInSession"] boolValue]; 

      //Sorts the friend into online or offline 
      if (friend.isOnline) { 
       [_onlineFriends addObject:friend]; 
      } else { 
       [_offlineFriends addObject:friend]; 
      } 
     } 

     //user object created with local data to test best friends array 
     OtherUser *tempUser = [[OtherUser alloc] initWithFirstname:@"John" 
                  Lastname:@"Egbert" 
                  Username:@"ectobiologist" 
                  UserID:[NSNumber numberWithInt:10] 
                 OnlineState:YES 
                 SessionState:NO]; 
     [_bestFriends addObject:tempUser]; 

     //User created with local data to compare to downloaded JSON users 
     OtherUser *tempUser2 = [[OtherUser alloc] initWithFirstname:@"Rose" 
                  Lastname:@"Lalonde" 
                  Username:@"tentacletherapist" 
                  UserID:[NSNumber numberWithInt:15] 
                 OnlineState:YES 
                 SessionState:NO]; 
     [_onlineFriends addObject:tempUser2]; 
    } 

    //Adds the arrays to the array array 
    self.arrays = [NSMutableArray arrayWithObjects:_bestFriends, _onlineFriends, _offlineFriends, nil]; 

    //Resets the table data 
    [self.tableView reloadData]; 
    NSLog(@"reloading data..."); 
} 

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"Creating Cell..."); 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    //Creates a user object from the proper index of the proper array (e.g. _onlineFriends[1]) 
    OtherUser *friend = [[_arrays objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

    // Configure Cell 
    UILabel *label = (UILabel *)[cell.contentView viewWithTag:10]; 
    [label setText:[friend fullname]]; 

    NSLog(@"Cell created!"); 
    return cell; 
} 

И мой файл FriendsTableViewController.h, на всякий случай:

@interface FriendsTableViewController : UITableViewController <NSURLConnectionDelegate> { 
    NSMutableData *_responseData; 
    NSMutableArray *_onlineFriends; 
    NSMutableArray *_bestFriends; 
    NSMutableArray *_offlineFriends; 
} 

@property NSMutableArray *arrays; 

Edit: В OtherUser файлы:

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

@interface OtherUser : NSObject 

@property (weak, nonatomic) NSNumber *userID; 
@property (weak, nonatomic) NSString *firstname; 
@property (weak, nonatomic) NSString *lastname; 
@property (weak, nonatomic) NSString *username; 
@property (nonatomic, assign) BOOL isOnline; 
@property (nonatomic, assign) BOOL isInSession; 
@property (weak, nonatomic) NSNumber *sessionID; 

- (id)initWithFirstname:(NSString *)firstName Lastname:(NSString *)lastName 
       Username:(NSString *)userName UserID:(NSNumber *)uID 
      OnlineState:(BOOL)online SessionState:(BOOL)inSession; 
- (id) init; 

- (NSString *) fullname; 

//OtherUser.m 

//Initializes an empty User object 
- (id)init { 
    self = [super init]; 
    if (self) { 
     self.userID = 0; 
     self.username = @""; 
     self.firstname = @""; 
     self.lastname = @""; 
     self.isOnline = NO; 
     self.isInSession = NO; 

     return self; 
    } 
    return nil; 
} 

- (id)initWithFirstname:(NSString *)firstName Lastname:(NSString *)lastName 
       Username:(NSString *)userName UserID:(NSNumber *)uID 
      OnlineState:(BOOL)online SessionState:(BOOL)inSession { 
    self = [super init]; 

    if (self) { 
     self.userID = uID; 
     self.username = userName; 
     self.firstname = firstName; 
     self.lastname = lastName; 
     self.isOnline = online; 
     self.isInSession = inSession; 

     NSLog(@"Friend %@ %@ created.", self.firstname, self.lastname); 

     return self; 
    } 
    return nil; 
} 

- (NSString *)fullname { 
    return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname]; 
} 
+1

Где находится OtherUser.h/.m ?? –

+0

Добавлено. Я должен был сначала включить его, извинения. – Shanghai

+2

свойство (*** слабый ***, неатомный) - это объясняет это. –

ответ

2

Вы объявили "Firstname", "фамилия" и другие свойства, как слабой:

@property (weak, nonatomic) NSString *firstname; 

, что означает, что они не сохраняют ссылки объект, и будет установлен на nil , если ссылочный объект будет освобожден. Это происходит, когда массив JSON arr отправляется из области. NSString литералы статически выделяются и никогда не освобождаются, вот почему Роза Лалонд не теряет здесь свойств.

Вы должны объявить свойства Objective-C, как сильного, или - в случае строк - в качестве скопировать:

@property (copy, nonatomic) NSString *firstname; 
// ... 
@property (strong, nonatomic) NSNumber *sessionID; 

Btw., Все приведения типов и stringWithString вызова в

friend.firstname = [NSString stringWithString:(NSString *)[item objectForKey:@"firstname"]]; 
friend.lastname = (NSString *)[item objectForKey:@"lastname"]; 
// ... 

не нужен, вы можете написать это просто как

friend.firstname = [item objectForKey:@"firstname"]; 
friend.lastname = [item objectForKey:@"lastname"]; 

или, используя (новое) индексацию обозначения:

friend.firstname = item[@"firstname"]; 
friend.lastname = item[@"lastname"]; 
Смежные вопросы