使用mutableArrayValueForKey进行NSMutableArray赋值和更新会导致结果不一致

时间:2015-01-20 19:22:55

标签: ios objective-c nsmutablearray

注意:问题已经过重新措辞,以便更清晰并使用新信息进行更新

mutableArrayValueForKey与分配给第二个对象中的变量的对象属性结合使用时遇到了问题。

我的模型对象包含多个NSMutableArray属性。

@interface LBYCardDeck : NSObject
@property(strong,nonatomic,readonly)NSMutableArray *removedCardDeck;
@property(strong,nonatomic)NSMutableArray *discardDeck;

我的视图对象包含基于枚举类型的特定NSMutableArray到变量的赋值。

@implementation LBYCardDeckView
{
    NSMutableArray* cardArray;
}

-(void)setDeckType:(LBYDeckType)deckType
{
    _deckType = deckType;
    switch (_deckType) {
        case LBYDTDiscards:
            cardArray = cardDeck.discardDeck;
            break;
        case LBYDTRemoved:
            cardArray = cardDeck.removedCardDeck;
            break;
        default:
            NSAssert(NO, @"Invalid Deck Type");
        break;
    }
}

根据模型中的属性是否声明为readonly,我得到两个不同的结果。如果声明属性readonly,一切都按预期工作。如果未声明属性readonly,则行为与在赋值期间使用copy的行为相同:并非后续更新发生后,数组中的所有元素都会反映在指定的变量中。

我已经通过将视图对象中的变量更改为属性来解决问题。

@property(weak,nonatomic,readonly)NSMutableArray *cardArray;

我很好奇这里发生了什么。为什么对变量的赋值不能按预期工作?

更新:

我将问题缩小到我用于KVO目的的mutableArrayValueForKey方法。

下面是一个示例程序,它演示了出现意外行为(错误?),似乎表明正在后台执行副本。更改属性readonly会产生不同的结果

@property(strong,nonatomic)NSMutableArray *mutableArray2;

@property(strong,nonatomic,readonly)NSMutableArray *mutableArray2;

Object1 .h

#import <Foundation/Foundation.h>

@interface Object1 : NSObject

@property(strong,nonatomic,readonly)NSMutableArray *mutableArray1;
@property(strong,nonatomic)NSMutableArray *mutableArray2;

-(void)array1Update:(id)obj;
-(void)array2Update:(id)obj;
@end

Object1 .m

#import "Object1.h"

@implementation Object1

-(id)init {
 self = [super init];
 _mutableArray1 = [[NSMutableArray alloc]init];
 _mutableArray2 = [[NSMutableArray alloc]init];
 return  self;
}
-(void)array1Update:(id)obj {
[[self mutableArrayValueForKey:NSStringFromSelector(@selector(mutableArray1))] addObject:obj];
}

-(void)array2Update:(id)obj {
[[self mutableArrayValueForKey:NSStringFromSelector(@selector(mutableArray2))] addObject:obj];
}
@end

Object2 .h

#import <Foundation/Foundation.h>
@interface Object2 : NSObject
-(void)assignMyArray:(NSMutableArray*)obj1MutableArray;
-(void)logContents;
@end

Object2 .m

#import "Object2.h"
@implementation Object2{
    NSMutableArray*myArray;
}
-(id)init{
    self = [super init];
    return  self;
}
-(void)assignMyArray:(NSMutableArray*)obj1MutableArray{
    myArray = obj1MutableArray;
}
-(void)logContents{
    NSLog(@"%@",myArray);
}
@end

ViewController .m

#import "ViewController.h"
#import "Object1.h"
#import "Object2.h"
@interface ViewController ()
@end
@implementation ViewController
{
Object1* obj1;
Object2* obj2Array1;
Object2* obj2Array2;
}
- (void)viewDidLoad {
[super viewDidLoad];
obj1 =[[Object1 alloc]init];
//add some data
[obj1 array1Update:@"1A"];
[obj1 array1Update:@"1B"];
[obj1 array2Update:@"2A"];
[obj1 array2Update:@"2B"];

//assign array 1 to obj2Array1
obj2Array1 =[[Object2 alloc]init];
[obj2Array1 assignMyArray:obj1.mutableArray1];

//assign array 2 to obj2Array2
obj2Array2 =[[Object2 alloc]init];
[obj2Array2 assignMyArray:obj1.mutableArray2];

//check values
[obj2Array1 logContents];
[obj2Array2 logContents];

//add some more data
[obj1 array1Update:@"1C"];
[obj1 array1Update:@"1D"];
[obj1 array2Update:@"2C"];
[obj1 array2Update:@"2D"];

//check values
[obj2Array1 logContents];
[obj2Array2 logContents];
}
@end

0 个答案:

没有答案