Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSMutableArray分配和使用mutableArrayValueForKey的更新会导致不一致的结果_Ios_Objective C_Nsmutablearray - Fatal编程技术网

Ios NSMutableArray分配和使用mutableArrayValueForKey的更新会导致不一致的结果

Ios NSMutableArray分配和使用mutableArrayValueForKey的更新会导致不一致的结果,ios,objective-c,nsmutablearray,Ios,Objective C,Nsmutablearray,注意:为清晰起见,问题已重新措辞,并使用新信息进行更新 当将mutableArrayValueForKey与分配给第二个对象中变量的对象属性结合使用时,我遇到了一个问题 我的模型对象包含多个NSMutableArray属性 @interface LBYCardDeck : NSObject @property(strong,nonatomic,readonly)NSMutableArray *removedCardDeck; @property(strong,nonatomic)NSMutabl

注意:为清晰起见,问题已重新措辞,并使用新信息进行更新

当将
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
方法

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

@property(strong,nonatomic)NSMutableArray *mutableArray2;
与:

@property(strong,nonatomic,readonly)NSMutableArray *mutableArray2;
目标1.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
目标2.h

#import <Foundation/Foundation.h>
@interface Object2 : NSObject
-(void)assignMyArray:(NSMutableArray*)obj1MutableArray;
-(void)logContents;
@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

复制对象时,即复制对象。如果您有一个属性不进行
复制
,那么您只需复制指针。我认为您感到困惑。将赋值发布到您认为会产生副本的可变数据模型属性。看起来一个拷贝是在幕后执行的,即使没有调用任何特定的拷贝。它是在setDeckType开关中执行的。您有该属性的自定义getter吗?
#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
#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