- objective-c - iOS 5 : Can you override UIAppearance customisations in specific classes?
- iphone - 如何将 CGFontRef 转换为 UIFont?
- ios - 以编程方式关闭标记的信息窗口 google maps iOS
- ios - Xcode 5 - 尝试验证存档时出现 "No application records were found"
我正在尝试使用 KVO 来监听 NSArray 属性上的集合更改事件。公开地,该属性是一个只读的 NSArray,但由 NSMutableArray ivar 支持,因此我可以修改集合。
我知道我可以将属性设置为新值以获得“设置”更改,但我对添加、删除、替换更改感兴趣。我如何正确通知 NSArray 的这些类型的更改?
@interface Model : NSObject
@property (nonatomic, readonly) NSArray *items;
@end
@implementation Model {
NSMutableArray *_items;
}
- (NSArray *)items {
return [_items copy];
}
- (void)addItem:(Item *)item {
[_items addObject:item];
}
@end
Model *model = [[Model alloc] init];
[observer addObserver:model
forKeyPath:@"items"
options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld)
context:NULL];
Item *item = [[Item alloc] init];
[model addItem:newItem];
观察者类:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"items"]) {
//Not called
}
}
最佳答案
首先,您应该了解 KVO 用于观察对象其属性的变化。也就是说,您不能像这样“观察数组”,而是观察索引集合属性。该属性可能由数组支持或以其他方式实现。只要符合KVC,按照KVO兼容的方式修改就可以了。 (因此,属性是 NSArray*
类型还是使用 NSMutableArray*
或其他任何类型实现都没有关系。)
因此,您正在观察 Model
的实例,以了解其 items
属性的变化。如果您希望观察者获得更改通知,您必须确保始终以符合 KVO 的方式修改 items
属性。
在我看来,最好的方法是实现 mutable indexed collection accessors并始终使用它们来修改属性。因此,您至少要实现其中一项:
- (void) insertObject:(id)anObject inItemsAtIndex:(NSUInteger)index;
- (void) insertItems:(NSArray *)objects atIndexes:(NSIndexSet *)indexes;
其中之一:
- (void) removeObjectFromItemsAtIndex:(NSUInteger)index;
- (void) removeItemsAtIndexes:(NSIndexSet *)indexes;
当属性由 NSMutableArray
支持时,上述方法是对 _items
上相应方法的直接包装。
您为修改属性而编写的任何其他方法都应该通过其中之一。因此,您的 -addItem:
方法将是:
- (void)addItem:(Item *)item {
[self insertObject:item inItemsAtIndex:[_items count]];
}
您还可以删除 items
属性的普通 getter,而只公开索引集合的 getter:
- (NSUInteger) countOfItems;
- (id) objectInItemsAtIndex:(NSUInteger)index;
不过,如果有典型的 getter,则没有必要。
(这些访问器的存在允许你实现一个非 NSArray
类型的对多属性。从 KVC 的角度来看,没有必要为任何实际的数组类型界面。)
就我个人而言,我不推荐这样做,但是一旦你有了这样的访问器,你也可以通过使用 -mutableArrayValueForKey 获取属性的类似
然后向它发送变异操作。因此,在这种情况下,您可以执行 NSMutableArray
的代理来改变属性:[[self mutableArrayValueForKey:@"items"] addObject:item]
。我不喜欢这样,因为我觉得键值编码是针对当键是数据的时候。它是动态的或存储在像 NIB 这样的数据文件中,在编译时是未知的。当您可以选择使用语言符号(例如选择器)来寻址属性时,对键名称进行硬编码是一种代码味道。
不过,就索引访问器而言,对于真正难以实现的操作(例如排序)来说,这是有道理的。
最后,您可以使用 NSKeyValueObserving
协议(protocol)的 -willChange...
和 -didChange...
方法在您直接修改属性的后备存储时发出更改通知,而无需通过 KVO 可以识别和识别的突变方法钩入。对于索引集合属性,这将是 -willChange:valuesAtIndexes:forKey:
和 -didChange:valuesAtIndexes:forKey:
方法。就我而言,这是一种更糟糕的代码味道。
关于ios - 由 NSMutableArray 支持的 NSArray 修改的 KVO 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24088953/
在 viewDidLoad 上,我的应用程序填充 NSMutableArray arrayOfHaiku,它是 NSDictionary 项的数组,如下所示: NSError *error; NS
我在 NSMutableArray 上是这样的: NSMutableArray *array = [NSMutableArray arrayWithObjects:@"0",@"0",@"0",@"0
我正在尝试设置我的 allArticlesArray 的内容,然后将附加对象附加到数组中。这是我的代码片段: [self.allArticlesArray setArray:newsArray]; [
我用 NSMutableArray 中的数据填充了 TableView ,一切正常。当我选择一个单元格(didSelectRowAtIndex)时,该项目将从数组中删除,正如它应该做的那样。现在我希望
我有一个 NSMutableArray 是我的代表,我也在我的一个 View Controller 中使用它。 所以在 viewDidLoad 我像这样制作我的 NSMutableArray 的可变副
我有 100 个元素的 NSMutableArray。 我想将“20 - 50”、“10 - 20”、“60 - 100”和 50 - 60. 元素加载到单独的 NSMutableArray 中,并将
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 9 年前。 Improve t
我在尝试将字符串的 NSMutableArray 共享给另一个类时遇到了一些问题。我有一个 tableView,其中填充了 Strings,我想将其添加到 NSMutableArray。然后在另一个
正如我们所知,数组是一个连续的内存分配。那么 NSMutableArray 大小将如何增加。 最佳答案 C 数组确实使用连续内存,C++ std::vector 也是如此,但是 NSMutableAr
我需要对一个数组进行排序,里面有一个数组,像这样: NSMutableArray * array_example = [[NSMutableArray alloc] init]; [array_e
这看起来很简单,但我只是得到一个空数组。 我想获取一个按下的按钮,找到它旁边的所有按钮(参见代码中的注释),并将所有找到的按钮添加到另一个 NSMutableArray。 然后我想遍历该数组并对每个按
我正在尝试在另一个 NSMutableArray 中添加 NSMutableArray。但我想做的是嵌套数组。 我当前的代码是: NSMutableArray *array1 = [NSMutab
我有三个类,即DepartmentViewController、DepartmentRequest、Department。这就像我从 DepartmentViewcontroller 发出部门请求,并
我正在尝试将 NSMutableArray 存储在 NSMutableArray 中。所以 var all:NSMutableArray = NSMutableArray() let localArr
这一定是那些错误之一,您一直盯着代码看很长时间,以至于找不到错误。 我有这个代码块,我在其中循环遍历一个包含多个 NSMutableArray 的 NSMutableArray: // FoodVi
我有一个包含 50 个条目的 NSMutableArray - 有什么简单的方法可以将其分成 5 个 NSMutableArray,每个 10 个条目。 最佳答案 是的,要划分 NSMutableAr
我想将 NSMutableArray 的 addObject 放入 NSMutableArray 中,那么我如何快速实现这一点。并检索它,所以请帮助我,因为现在我正在快速学习。 间接说我要二维数组是指
好吧: 我有 NSMutableArray 1 我还有 NSMutableArray 2 我想从数组 1 中删除与数组 2 中的对象匹配的所有对象。 有什么想法吗? 最佳答案 我刚刚打开文档,打印 N
我正在尝试制作 NSMutableArray 的深拷贝,其对象是与此类似的自定义类的实例: @interface CustomParent : NSObject @property NSInteger
我知道你们可能会觉得这是一个重复的问题。但我对我的项目的这个问题搞砸了。 现在转到这个问题,我已经采取了NSMutableArray命名为 arr1包含字符串值,例如 @"34" , @"40"等等。
我是一名优秀的程序员,十分优秀!