为什么我的对象发生了意外的变化



我有一个非常基本的例子,在这个例子中,我从JSON将一些数据读取到一个类中,而我的对象不知何故被损坏了。我怀疑我遗漏了一些关于房地产/ARC如何运作的细节,但我不确定它是什么,也不确定我会如何追踪它。

我已经减少了原始代码,所以问题很明显。然而,这意味着我不清楚为什么要使用自定义属性等——我的真实代码中有更多的功能。。。

这个问题可以在Test.m文件的最后一行中看到。第一个构造的对象现在包含来自第二个对象的数据,而不是它最初包含的值。

任何关于我做错了什么和/或如何追踪这类问题的建议都将不胜感激。

ANB注意事项

@interface ANBNote : NSObject
@property (nonatomic,readwrite) NSArray* references;
- (id)initWithJson:(NSDictionary*)data;
@end

ANB注意事项

#import "ANBNote.h"
@implementation ANBNote
NSArray * _references;
-(id) init {
  if(!(self=[super init])) return nil;
  _references=@[];
  return self;
}
-(id)initWithJson:(NSDictionary *)jsonObject {      
  if(!(self = [self init] ) ) { return nil; }    
  _references = jsonObject[@"references"];    
  return self;
}
-(void) setReferences:(NSArray *)references {
  _references = references;
}
-(NSArray *)references {
  return _references;
}    
@end

测试.m

...
NSDictionary * d1 = @{@"references":@[@"r1",@"r2"]};
NSDictionary * d2 = @{@"references":@[@"q1",@"q2"]};
ANBNote * n1 = [[ANBNote alloc] initWithJson:d1];
NSLog(@"R1 = %p, %@", n1.references, n1.references); // Prints r1, r2 - as expected
ANBNote * n2 = [[ANBNote alloc] initWithJson:d2];
NSLog(@"R2 = %p, %@", n2.references, n2.references); // Prints q1, q2 - as expected
NSLog(@"R1 = %p, %@", n1.references, n1.references); // Prints q1, q2 - Oh No!

请注意,如果我删除自定义引用属性函数并依赖编译器生成的版本,那么一切似乎都会正常运行。

这不是ivar:

@implementation ANBNote
NSArray * _references;

这是全球性的。类的所有实例只有一个,而不是每个实例一个。当下一个实例设置它时,前一个实例会看到新值,因为它是同一个变量。你需要把它放在花括号里,使它成为ivar:

@implementation ANBNote
{
    NSArray * _references;
}

不过,不需要显式声明变量——只要使用默认的合成名称(下划线+属性名称),您仍然可以自己实现访问器,并让编译器创建ivar。

答案很简单,您将NSArray*_references定义为静态变量,而不是私有变量。这样做

@implementation ANBNote{
    NSArray * _references;
}

除此之外,从Xcode 4开始,您不必在实现文件中定义_references对象。您只需在头文件中设置一个变量,然后只需在其名称前键入_即可访问其专用访问器。

例如

@interface ANBNote
@property(strong , nonatomic) NSArray *references;
@end
@implementation ANBNote
-(id) initWithArray:(NSArray *) ar{
    if(self)
        _references = [NSArray arrayWithArray:ar];
    return self;
}
@end

这不是问题的根源,而是将initWithJson:更改为

-(id)initWithJson:(NSDictionary *)jsonObject
{      
  if(!(self = [super init] ) ) { return nil; }    
  _references = jsonObject[@"references"];    
  return self;
}

抛弃自定义的setter和getter(你显然不需要它们)。

在您的情况下,您可以简单地使用声明属性

@property (strong) NSArray* references;

NSArray * _references;更改为:

@synthesize references = _references;

您也可以在您的案例中省略@synthesize行。

同时将_references = jsonObject[@"references"];更改为:

_references = [NSArray arrayWithArray:jsonObject[@"references"]];

综上所述:

ANB注意事项

@interface ANBNote : NSObject
@property (strong) NSArray* references;
- (id)initWithJson:(NSDictionary*)data;
@end

ANB注意事项

#import "ANBNote.h"
@implementation ANBNote
-(id) init {
  if(!(self=[super init])) return nil;
  _references=@[];
  return self;
}
-(id)initWithJson:(NSDictionary *)jsonObject {      
  if(!(self = [super init] ) ) { return nil; }    
  _references = [NSArray arrayWithArray:jsonObject[@"references"]];    
  return self;
}
@end

相关内容

最新更新