[英]Cocoa: using observer in a model
我试图了解如何实现真正的Cocoa MVC,如图4-7所示。
这是一个链接
图4-7显示了该模型使用模式观察器来通知控制器(被动MVC)。 我以这种方式在模型中实现观察者
@interface IADataManager : NSObject
//MARK: Parsed Feed With IANewsDataObj
@property (nonatomic,retain) NSMutableArray *feedArray;
//MARK: Model use Singelton Pattern
+ (IADataManager *) sharedInstance;
//MARK: Observation methods
- (void) addListener:(id<IADataManagerListener>) listener;
- (void) removeListener:(id<IADataManagerListener>) listener;
//MARK: Business Logic
- (void) loadFeedFromNetwork;
- (void) loadFeedFromDataBase;
- (void) loadImageForTarget:(id<IADataManagerListener>) target
AtIndexPath:(NSIndexPath *) indPath;
- (void) saveFeedToDataBase;
@end
@protocol IADataManagerListener <NSObject>
- (void) IADataManager :(IADataManager *) dataMng
didRefreshWithError :(NSError *) error;
- (void) IADataManager :(IADataManager *) dataMng
didLoadImageForIndexPath :(NSIndexPath *) indexPath;
- (void) IADataManager :(IADataManager *) dataMng
didLoadWithError :(NSError *) error;
@end
- (void) addListener:(id<IADataManagerListener>) listener
{
if([self.listeners indexOfObject:listener] == NSNotFound && listener)
[self.listeners addObject:listener];
}
- (void) removeListener:(id<IADataManagerListener>) listener
{
if([self.listeners indexOfObject:listener] !=NSNotFound && listener)
[self.listeners removeObject:listener];
}
//Notification example
- (void) handleLoadedNews:(NSArray *) loadedNews
{
[self.feedArray addObjectsFromArray:loadedNews];
[self.listeners enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
objc_msgSend(obj, @selector(IADataManager:didRefreshWithError:),self,nil);
}];
}
我想知道,是否有更好的方法在模型中实现观察者? 例如,使用KVO或NSNotificationCenter。 但是问题是,在KVO和NSNotificationCenter的帮助下,我不能使用带有超过1个参数的选择器。 例如,
- (void) DataManager:(DataManager *) dm withObj1:(Obj1*) obj1 Obj1:(Obj2*) obj2 Obj3:(Obj3*) obj3
非常感谢!
But problem is that with the help of KVO and NSNotificationCenter i can not use selectors with more than 1 argument.
您可以!!!
将所有选择器存储在数组或字典中,然后传递该单个对象。
我认为使用委派或阻止将是理想的选择。要在视图控制器中获取回调,可以使用委派方法或阻止。 我认为wlll是MVC设计模式的理想方法。
通常,KVO是更好的选择。 例:
在IDataManager中:
- (void) handleLoadedNews:(NSArray *) loadedNews
{
[self willChangeValueForKey:@"feedsArray"]; //Also, see - (void)willChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key
[self.feedsArray addObjectsFromArray:arr];
[self didChangeValueForKey:@"feedsArray"]; //Also, see - (void)didChange:(NSKeyValueChange)changeKind valuesAtIndexes:(NSIndexSet *)indexes forKey:(NSString *)key
}
并且,在ViewController中:
- (void) viewDidLoad {
....
[[IADataManager sharedInstance] addObserver:self forKeyPath:@"feedsArray" options:0 context:NULL];
}
- (void) viewWillUnload {
....
[[IADataManager sharedInstance] removeObserver:self forKeyPath:@"feedsArray"];
}
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
//if keyPath is "feedsArray", refresh my views
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.