Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c Cocoa:在模型中使用观察者_Objective C_Ios - Fatal编程技术网

Objective c Cocoa:在模型中使用观察者

Objective c Cocoa:在模型中使用观察者,objective-c,ios,Objective C,Ios,我试图理解如何实现真正的Cocoa MVC,如本链接中的图4-7所示 这里有一个链接 图4-7显示了模型使用模式观察者通知控制器(被动MVC)。 我以这种方式在模型中实现了observer @interface IADataManager : NSObject //MARK: Parsed Feed With IANewsDataObj @property (nonatomic,retain) NSMutableArray *feedArray; //MARK: Model use Sin

我试图理解如何实现真正的Cocoa MVC,如本链接中的图4-7所示

这里有一个链接

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

@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的帮助下,我不能将选择器与多个参数一起使用。

你可以


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

我认为使用委派或块将是理想的选择。要在视图控制器中获取回调,可以使用委派方法或块。我认为WL将是MVC设计模式的理想方法。

我认为使用委派或块将是理想的方法。要在视图控制器中获得回调,可以使用委派方法或块。我认为这将是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
}

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
}