【问题标题】:Data Loss When Passing Object传递对象时数据丢失
【发布时间】:2017-06-12 12:40:42
【问题描述】:

我有一个对象

@interface QuestionViewModel : NSObject

@property (nonatomic, assign) NSInteger questionId;
@property (nonatomic, strong) NSString *questionText;
@property (nonatomic, assign) NSInteger questionNumber;
@property (nonatomic, strong) NSArray *choices;

@property (nonatomic, strong) QuestionViewModel *nextQuestion;
@property (nonatomic, strong) QuestionViewModel *previousQuestion;

@end

我知道当我填充此对象时它是成功的,并且所有属性都已完全正确地初始化。

但是,当我像这样传递这个对象时:

*这是一个不同的类(它不在上面定义的 NSObject 中)。

@property (nonatomic, strong) QuestionViewModel *currentQuestion;

- (void)nextQuestion
{
    [self loadQuestion:self.currentQuestion.nextQuestion];
}

- (void)loadQuestion:(QuestionViewModel *)question
{
    self.currentQuestion = question;
    .
    .
    .
}

question.nextQuestionquestion.previousQuestionnil

为什么当我传递这个对象时,后续对象(nextQuestion 和 previousQuestion)会变为 nil?似乎该对象正在执行浅拷贝而不是深拷贝,但不确定。

似乎有一些我不知道的基础知识。

【问题讨论】:

  • 对象根本没有被复制。 question 指向一个问题,这个指针被分配给currentQuestion。签入nextQuestionself.currentQuestionself.currentQuestion.nextQuestionself.currentQuestion.nextQuestion.nextQuestion 的值。
  • self.currentQuestion.nextQuestion.nextQuestion 为零。 self.currentQuestion.nextQuestion 对列表中的第一个问题有效,但对所有其他问题为零。
  • 我认为您正在创建与其自身(QuestionViewModel)相同类型的对象的属性(nextQuestion,previousQuestion)这一事实正在创建某种递归问题。作为一种策略,这有点令人困惑。将 nextQuestion 和 previousQuestion 存储为单独的类实例并在您实例化它们的任何类中相应地更新它们可能会更好吗?
  • 不,将 nextQuestion 和 previousQuestion 存储为单独的类实例不是一个好主意。指向同一类的另一个实例是可以的。所有问题都正确初始化了吗?他们是否指向下一个和上一个问题?
  • 我认为您没有正确设置下一个和上一个问题。您不仅会丢失数据。对象在其地址作为参数传递时不会改变。

标签: objective-c pass-by-reference pass-by-value nscopying pass-by-pointer


【解决方案1】:

我最终更改了模型以更准确地反映链接列表。当我存储上一个和下一个对象时,它很接近,但我最终更改了上一个和下一个属性来存储对象的索引,而不是实际的对象。

@property (nonatomic, assign) NSInteger nextQuestionIndex;
@property (nonatomic, assign) NSInteger previousQuestionIndex;

【讨论】:

  • 您确实存储了地址。 QuestionViewModel * 是一个指针。
【解决方案2】:

我认为您需要先初始化您的子类QuestionViewModel NSObject。在QuestionViewModel.m 文件中,您可以覆盖init 方法。像这样的:

- (id)init {
    if((self = [super init])) {
        // Set whatever init parameters you need here
    }
    return self;
}

然后,在您尝试使用此方法的类中,只需调用:

-(void)viewDidLoad {
    QuestionViewModel *currentQuestion = [[QuestionViewModel  alloc] init];
}

【讨论】:

  • 我实现了这个,但没有任何区别。属性仍然为零。不过很好的修复尝试。
猜你喜欢
  • 2016-12-23
  • 2015-05-10
  • 2019-09-10
  • 2020-08-03
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 2023-03-08
  • 2016-05-31
相关资源
最近更新 更多