2015-05-14 1 views
1

У меня есть класс LearnfestItem.h:Доступ свойств из объекта в NSMutableArray не работает

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


@interface LearnfestItem : NSObject 

@property (strong, nonatomic) NSString * itemId; 
@property (strong, nonatomic) NSString * itemTitle; 
@property (strong, nonatomic) NSString * itemDescription; 
@property (strong, nonatomic) NSString * itemContent; 
@property (strong, nonatomic) NSString * itemType; 
@property (strong, nonatomic) UIImage * itemImage; 
@property (strong, nonatomic) NSDate * itemRegistered; 

-(id)initWithData:(NSDictionary *)data andImage:(UIImage *)image; 

@end 

& Object.m:

#import "LearnfestItem.h" 
#import "Defaults.h" 

@implementation LearnfestItem 

-(id)init 
{ 
    self = [self initWithData:nil andImage:nil]; 
    return self; 
} 

-(id)initWithData:(NSDictionary *)data andImage:(UIImage *)image 
{ 
    self = [super init]; 

    self.itemId = data[ITEM_ID]; 
    self.itemTitle = data[ITEM_TITLE]; 
    self.itemDescription = data[ITEM_DESCRIPTION]; 
    self.itemContent = data[ITEM_CONTENT]; 
    self.itemType = data[ITEM_TYPE]; 
    self.itemImage = image; 
    self.itemRegistered = data[ITEM_REGISTERED]; 

    return self; 
} 

@end 

В моем UIViewController у меня есть UITableView, который создает NSMutableArray из LearnfestItems в пределах cellForRowAtIndexPath метод:

LearnfestItem * createLearnfestItem = [[LearnfestItem alloc] initWithData:learnfestItemDictionary andImage:learnfestItemImage]; 

    NSLog(@"Insert learnfest item with id: %@ at index %li", createLearnfestItem.itemId, (long)row); 

    [self.learnfestItemObjects insertObject:createLearnfestItem atIndex:row]; 

На didSelectRowAtIndexPath я хочу получить LearnfestItem от NSMutableArray я это сделать по телефону:

self.selectedLearnfestItem = [self.learnfestItemObjects objectAtIndex:indexPath.row]; 

Тогда я хочу, чтобы отправить его на другой контроллер представления, чтобы представить данные, которые я сделать это в prepareForSegue segement:

LearnfestItemViewController * learnfestVC = [segue destinationViewController]; 
     NSLog(@"Sending learnfest item with id: %@", self.selectedLearnfestItem.itemId); 
     learnfestVC.item = self.selectedLearnfestItem; 

Когда я пытаюсь получить доступ к своим LearnfestItem's свойства в cellForRowAtIndexPath. Все, что я получаю, равно null ... и т. Д. В других методах делегата в таблице. Может ли кто-нибудь определить, что я делаю неправильно? Спасибо

+0

Вы инициализируетесь NSMutableArray? – iPhone

+0

Да, я вызываю его в 'viewDidLoad' -' self.learnfestItemObjects = [[NSMutableArray alloc] init]; ' – cwiggo

+0

Попробуйте следующий код [self.learnfestItemObjects addObject: createLearnfestItem]; – iPhone

ответ

0

В коде, который вы показываете, отсутствует вся проверка ошибок и проверки действительности. При использовании NSAssert() и item.length/item.count проверяет, что вы будете знать, что происходит.

Однако, основываясь на своем коде я хотел бы предложить две вещи:

  1. Все объекты, которые также имеют изменяемую версию следует использовать «копировать» свойства. Теперь у вас есть «сильный» указатель на данные, полученные методом init, но если вы сбросите исходную данную переменную данных в другую точку (например, повторное использование одной переменной данных внутри цикла для запуска нескольких элементов), тогда ... Я не знаю на что указывают свойства элемента LearnfestItem.
  2. Убедитесь, что ваш элемент LearnfestItemViewController * тоже является копией.

Я предполагаю, что все инициализировано правильно, но после этого данные исчезают.

Например:

@property (nonatomic, copy) NSString * itemId; // Safe 
@property (nonatomic, strong) NSString * itemId; // Not safe 

Когда класс свойство имеет непостоянные вариации (например, NSString против NSMutableString против MyMutableString), копия безопаснее. Использование сильного будет создавать указатель на исходные данные, которые могли бы быть изменчивым экземпляром и впоследствии могут быть изменены. Использование сильной подсказки всегда указывает на исходные данные, даже после того, как они были изменены.

Вторая часть:

learnfestVC.item = self.selectedLearnfestItem; 

Ваш LearnfestItemViewController содержит некоторые свойства, связанные с классом LearnfestItem. Убедитесь, что это тоже копия. При использовании segues вызывающий объект довольно часто просто исчезает.Убедитесь, что ваш новый контроллер имеет локальную копию всех необходимых данных (или используйте делегат протокола, но это более длительное обсуждение).

+0

любой шанс вы могли бы показать нам некоторую реализацию кода .. где добавить копию? – cwiggo

+0

что делать с помощью программы LearnfestItemViewController? Где я должен это поставить? при создании или? – cwiggo

+0

Я немного борюсь с этим. Это просто не работает :( – cwiggo

0

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

Это быстрое и грязное «техническое обслуживание» для вашего кода. Из чего вы должны выйти, это некоторые идеи, что нужно проверять, где и как. В нормальных ситуациях это слишком много, но теперь у вас есть таинственная проблема и нужно ее найти. Это может быть трудная и монотонная работа.

@import Foundation; 
@import UIKit; 

@interface LearnfestItem : NSObject 
@property (copy, nonatomic) NSString *itemId; 
@property (copy, nonatomic) NSString *itemTitle; 
@property (copy, nonatomic) NSString *itemDescription; 
@property (copy, nonatomic) NSString *itemContent; 
@property (copy, nonatomic) NSString *itemType; 
@property (strong, nonatomic) UIImage *itemImage; 
@property (strong, nonatomic) NSDate *itemRegistered; 
- (instancetype)initWithData:(NSDictionary *)data andImage:(UIImage *)image;  
@end 

Object.m:

#import "Defaults.h" 
#import "LearnfestItem.h" 

@implementation LearnfestItem 

- (instancetype)init 
{ 
    self = [self initWithData:nil andImage:nil]; 
    return self; 
} 

- (instancetype)initWithData:(NSDictionary *)data andImage:(UIImage *)image 
{ 
    NSAssert(data.length, @"My Assert: missing data"); 
    NSAssert(image, @"My Assert: missing image"); 
    if ((self = [super init])) 
    { 
     // TODO: nil ok, if doesn't exist? 
     _itemId = data[ITEM_ID]; 
     _itemTitle = data[ITEM_TITLE]; 
     _itemDescription = data[ITEM_DESCRIPTION]; 
     _itemContent = data[ITEM_CONTENT]; 
     _itemType = data[ITEM_TYPE]; 
     _itemImage = image; 
     _itemRegistered = data[ITEM_REGISTERED]; 
    } 
    return self; 
} 

@end 

"(оригинальный текст) В моем UIViewController У меня есть UITableView, который создает NSMutableArray из LearnfestItems в рамках метода cellForRowAtIndexPath:"

NSAssert(learnfestItemDictionary.count, @"My Assert: missing dict"); 
NSAssert(learnfestItemImage, @"My Assert: missing image"); 
LearnfestItem *createLearnfestItem = [[LearnfestItem alloc] initWithData:learnfestItemDictionary andImage:learnfestItemImage]; 

NSLog(@"Insert learnfest item with id: %@ at index %@", createLearnfestItem.itemId, @(row)); 
NSAssert(createLearnfestItem, @"My Assert: missing item"); 
NSAssert(self.learnfestItemObjects.count > row, @"My Assert: learnfestItemObjects"); 
self.learnfestItemObjects[row] = createLearnfestItem; 

" (исходный текст) On didSelectRowAtIndexPath Я хочу получить LearnfestItem из NSMutableArray. Я делаю это, вызывая: «

NSAssert(self.learnfestItemObjects.count > indexPath.row, @"My Assert: learnfestItemObjects"); 
self.selectedLearnfestItem = self.learnfestItemObjects[indexPath.row]; 

«(оригинальный текст) Затем я хочу, чтобы отправить его на другой контроллер представления, чтобы представить данные, которые я сделать это в сегменте prepareForSegue:»

LearnfestItemViewController *learnfestVC = (LearnfestItemViewController *)[segue destinationViewController]; 
NSLog(@"Sending learnfest item with id: %@", self.selectedLearnfestItem.itemId); 
learnfestVC.item = self.selectedLearnfestItem;