首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Cocoa:在模型中使用观察者

Cocoa:在模型中使用观察者
EN

Stack Overflow用户
提问于 2012-12-24 17:59:22
回答 3查看 366关注 0票数 1

我正在尝试理解如何实现真正的Cocoa MVC,如图4-7所示。

这里有一个链接

http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW1

图4-7显示了模型使用模式观察者来通知控制器(被动MVC)。我以这样的方式在我的模型中实现了观察者

代码语言:javascript
运行
复制
@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个参数的选择器。例如,

代码语言:javascript
运行
复制
 - (void) DataManager:(DataManager *) dm withObj1:(Obj1*) obj1  Obj1:(Obj2*) obj2  Obj3:(Obj3*) obj3

非常感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-12-24 20:34:24

KVO通常是更好的选择。示例:

在IDataManager中:

代码语言:javascript
运行
复制
- (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中:

代码语言:javascript
运行
复制
- (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
}
票数 0
EN

Stack Overflow用户

发布于 2012-12-24 18:12:22

But problem is that with the help of KVO and NSNotificationCenter i can not use selectors with more than 1 argument.

你可以的!

将所有选择器存储在数组或字典中,然后传递单个对象。

票数 1
EN

Stack Overflow用户

发布于 2012-12-24 19:19:53

我认为在视图控制器中使用委托或块将是理想的one.To get回调,您可以使用委托方法或块。我认为这将是MVC设计模式的理想方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14019795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档