【问题标题】:Accessing properties from Object within NSMutableArray not working从 NSMutableArray 中的对象访问属性不起作用
【发布时间】:2015-05-14 11:14:30
【问题描述】:

我有课程LearnfestItem.h

#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,它在cellForRowAtIndexPath 方法中创建NSMutableArrayLearnfestItems

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 我想从NSMutableArray 接收LearnfestItem 我通过调用来做到这一点:

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;

当我尝试访问cellForRowAtIndexPath 中的LearnfestItem's 属性时。我得到的只是空......等等在我的其他表视图委托方法中......有人能发现我做错了什么吗?谢谢

【问题讨论】:

  • 你初始化NSMutableArray了吗?
  • 是的,我叫它viewDidLoad - self.learnfestItemObjects = [[NSMutableArray alloc] init];
  • 试试下面的代码 [self.learnfestItemObjects addObject:createLearnfestItem];
  • @iPhone 不起作用,因为我需要稍后从数组索引中检索对象。
  • @Chris 您是否检查过您作为参数转发的字典是否具有有效的数据内容?否则源代码看起来不错。

标签: ios objective-c iphone uitableview nsobject


【解决方案1】:

您显示的代码缺少所有错误和有效性检查。当使用 NSAssert()item.length/item.count 检查时,您会知道发生了什么。

但是,根据您的代码,我建议两件事:

  1. 所有具有可变版本的对象都应使用“复制”属性。现在您有了指向通过 init 方法接收的数据的“强”指针,但是如果您将最初给定的数据变量重置为指向其他地方(例如,在 for 循环中重用一个数据变量来初始化多个项目),那么......我不知道您的 LearnfestItem 项目属性将指向什么。
  2. 确保您的 LearnfestItemViewController *item 也是副本。

我的猜测是一切都已正确初始化,但之后数据消失了。

例如:

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

当您的属性类具有可变变体时(例如 NSString vs. NSMutableString vs. MyMutableString),复制更安全。使用 strong 将创建一个指向原始数据的指针,该指针可能是一个可变实例,并且可以在之后进行修改。使用 strong 将始终指向原始数据,即使已更改。

第二部分:

learnfestVC.item = self.selectedLearnfestItem;

您的 LearnfestItemViewController 包含一些与 LearnfestItem 类相关的属性。确保它也是副本。使用 segue 时,调用对象通常会消失。 确保您的新控制器具有所有所需数据的本地副本(或使用协议委托,但这是一个较长的讨论)

【讨论】:

  • 有没有机会向我们展示一些代码实现......在哪里添加副本?
  • 让 LearnfestItemViewController 成为副本怎么样?我应该把这个放在哪里?在实例化或?
  • 我为此苦苦挣扎。它只是不工作:(
【解决方案2】:

添加错误和数据有效性检查将使您的任务更容易。与其在事后试图弄清楚为什么某些事情不工作,不如在事情不符合您的预期时收到通知。

这里是您的代码的快速而肮脏的“维护”。你应该从中得到一些想法,检查什么,在哪里以及如何检查。在正常情况下,这是矫枉过正,但现在你有一个神秘的问题,需要找到它。这可能是一项艰巨而单调的工作。

@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

对象.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,它在 cellForRowAtIndexPath 方法中创建了一个 NSMutableArray 的 LearnfestItems:”

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;

“(原文)在 didSelectRowAtIndexPath 上我想从 NSMutableArray 接收 LearnfestItem 我通过调用来做到这一点:”

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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多