注意:问题已经过重新措辞,以便更清晰并使用新信息进行更新
将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