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