1

このリンクの図4-7のように、真のCocoaMVCを実装する方法を理解しようとしています。

ここにリンクがあります

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

図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の助けを借りて、複数の引数を持つセレクターを使用できないことです。例えば、

 - (void) DataManager:(DataManager *) dm withObj1:(Obj1*) obj1  Obj1:(Obj2*) obj2  Obj3:(Obj3*) obj3

どうもありがとう!

4

3 に答える 3

1

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

あなたはできる!!!

すべてのセレクターを配列またはディクショナリに格納してから、その単一のオブジェクトを渡します。

于 2012-12-24T10:12:21.737 に答える
0

委任またはブロックの使用が理想的だと思います。ViewControllerでコールバックを取得するには、委任メソッドまたはブロックを使用できます。wlllはMVCデザインパターンにとって理想的なアプローチだと思います。

于 2012-12-24T11:19:52.677 に答える
0

通常、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
}
于 2012-12-24T12:34:23.667 に答える