gpt4 book ai didi

iphone - 可变集合作为属性的最佳实践

转载 作者:可可西里 更新时间:2023-11-01 06:23:30 26 4
gpt4 key购买 nike

我打算使用 NSMutableDictionary 属性来存储游戏数据(例如分数、设置等...)。

@property (nonatomic, copy) NSMutableDictionary *gameData;

在研究为什么我发现属性没有“mutablecopy”选项时 this discussion ,已接受的答案指出:

the right way to do it is not to make the mutable array a property

那么在现代 Objective-C 中将可变集合作为属性处理的最佳方式是什么?

最佳答案

类很少公开集合对象的可变属性,因为它似乎会破坏封装。

尽管如此,还是有可能有意义的场合:例如,您可以为一些内部管理的集合返回一个 KVO 代理(使用 KVC's mutableArrayValueForKey:)。

在这些情况下,是否将 getter 声明为属性或普通方法并不重要。不过,在属性的情况下,它不应该是 copy 属性。

为了使这一点更清楚,这里有一个例子。我们有一个声明单个公共(public) getter 的类:

@interface Foo : NSObject

@property (strong, readonly) NSMutableArray *publicBars;

@end

该实现管理一个名为 _bars 的封装的私有(private)可变数组:

@implementation Foo
{
NSMutableArray *_bars;
}

这个数组的元素由 KVC to-many accessors 公开:

- (NSUInteger)countOfBars
{
return [_bars count];
}

- (id)objectInBarsAtIndex:(NSUInteger)idx
{
return _bars[idx];
}

- (void)insertObject:(id)object inBarsAtIndex:(NSUInteger)idx
{
if (_bars == nil)
_bars = [NSMutableArray array];
[_bars insertObject:object atIndex:idx];
}

- (void)removeObjectFromBarsAtIndex:(NSUInteger)idx
{
[_bars removeObjectAtIndex:idx];
}

这是花哨的部分:我们通过返回 a KVC proxy that reflects and mutates the internal state 来实现公共(public)属性不暴露内部ivars。它仅通过使用上面定义的公共(public)访问器来更改内部数组。

- (NSMutableArray *)publicBars
{
return [self mutableArrayValueForKey:@"bars"];
}

@end

我们可以使用代理来更改内部集合:

Foo *foo = [[Foo alloc] init];

NSMutableArray *bars = foo.publicBars;

[bars addObject:@1];
[bars addObject:@2];
[bars removeObjectAtIndex:0];

// Now the internal _bars array is @[ @2 ].

在 Cocoa 中有这种模式和类似模式的实际例子。例如,-[NSTextView textStorage] 返回内部后备存储(从 NSMutableAttributedString 派生的对象)。虽然不是集合对象,但它是一个可变对象,它将突变传递给它的宿主对象,即 TextView 。

关于iphone - 可变集合作为属性的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14814662/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com