V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
cralison
V2EX  ›  iDev

解决“单接口,多类”架构设计的回调问题

  •  
  •   cralison · 2015-09-07 01:59:29 +08:00 · 1394 次点击
    这是一个创建于 3372 天前的主题,其中的信息可能已经有所发展或是发生改变。

    全力推动信息,而非照顾他人感受

    最终效果:

    alt text

    alt text

    工程目录:

    alt text

    代码:

    APIInterface.h

    #ifndef CallBack_APIInterface_h
    #define CallBack_APIInterface_h
    @protocol APIInterface <NSObject>
    
    - (void )loadData;
    @end
    #endif
    

    APIParamSourceInterface.h

    #import "APIInterface.h"
    
    #ifndef CallBack_APIParamSourceInterface_h
    #define CallBack_APIParamSourceInterface_h
    @protocol APIParamSourceInterface <NSObject>
    
    - (NSDictionary *)paramSourceAPIHandle:(id<APIInterface>)apiHandle;
    @end
    #endif
    

    APICallbackInterface.h

    #import "APIInterface.h"
    
    #ifndef CallBack_APICallbackInterface_h
    #define CallBack_APICallbackInterface_h
    @protocol APICallbackInterface <NSObject>
    
    - (void )listWtihData:(NSArray *)data apiHandle:(id<APIInterface>)apiHandle;
    @end
    #endif
    

    APIHandle.h

    #import <Foundation/Foundation.h>
    #import "APIInterface.h"
    #import "APIParamSourceInterface.h"
    #import "APICallbackInterface.h"
    
    @interface APIHandle : NSObject<APIInterface>
    @property (nonatomic, strong ) NSMutableData *receiveData;
    @property (nonatomic, weak ) id<APIParamSourceInterface> paramSourceHandle;
    @property (nonatomic, weak ) id<APICallbackInterface> callbackHandle;
    @end
    

    APIHandle.m

    #import "APIHandle.h"
    
    @implementation APIHandle
    
    - (void )loadData
    {
        self.receiveData = [[NSMutableData alloc]init];
        NSDictionary *paramSource = [self.paramSourceHandle paramSourceAPIHandle:self];
        NSURL *url = [[NSURL alloc]initWithString:paramSource[@"URLString"]];
        NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url];
        NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
    }
    
    - (void )connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
        [self.receiveData appendData:data];
    }
    
    - (void )connectionDidFinishLoading:(NSURLConnection *)connection
    {
        NSError *error = nil;
        id data = [NSJSONSerialization JSONObjectWithData:self.receiveData options:NSJSONReadingAllowFragments error:&error];
        NSLog (@"%@ data\n%@",self,data );
    
        [self.callbackHandle listWtihData:data apiHandle:self];
    }
    @end
    

    HotAPIHandle.h

    #import "APIHandle.h"
    
    @interface HotAPIHandle : APIHandle
    
    @end
    

    HotAPIHandle.m

    #import "HotAPIHandle.h"
    
    @implementation HotAPIHandle
    
    @end
    

    LatestAPIHandle.h

    #import "APIHandle.h"
    
    @interface LatestAPIHandle : APIHandle
    
    @end
    

    LatestAPIHandle.m

    #import "LatestAPIHandle.h"
    
    @implementation LatestAPIHandle
    
    @end
    

    ViewController.h

    #import <UIKit/UIKit.h>
    #import "APIInterface.h"
    #import "APIParamSourceInterface.h"
    #import "APICallbackInterface.h"
    
    @interface ViewController : UIViewController<APIParamSourceInterface,APICallbackInterface>
    
    @property (nonatomic, weak ) id<APIInterface> hotAPIHandel;
    @property (nonatomic, weak ) id<APIInterface> latestAPIHandel;
    @end
    

    ViewController.m

    #import "ViewController.h"
    
    @interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
    @property (nonatomic, strong ) NSArray *list;
    @property (nonatomic, strong ) UITableView *tableView;
    @end
    
    @implementation ViewController
    
    - (void )viewDidLoad {
        [super viewDidLoad];
    
        [self initUI];
        [self.hotAPIHandel loadData];
    }
    
    -(void )initUI
    {
        self.title = @"最热-最新主题";
        CGRect frame = [[UIScreen mainScreen]bounds];
        self.tableView = [[UITableView alloc]initWithFrame:frame];
        self.tableView.delegate = self;
        self.tableView.dataSource = self;
        [self.view addSubview:self.tableView];
    }
    
    - (NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger )section
    {
        return self.list.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *cellIdentifier = @"cellIdentifier";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        if (!cell ) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
        }
        NSDictionary * data =self.list[indexPath.row];
    
        return [self configureWithCell:cell data:data];
    }
    
    - (UITableViewCell *)configureWithCell:(UITableViewCell *)cell data:(NSDictionary *)data
    {
        cell.textLabel.text = data[@"title"];
        cell.imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http:%@",data[@"member"][@"avatar_mini"]]]]];
        return cell;
    }
    
    -(NSDictionary *)paramSourceAPIHandle:(id<APIInterface>)apiHandle
    {
        if ([apiHandle isKindOfClass:[self.hotAPIHandel class]]) {
            return @{
                     @"URLString" : @"https://www.v2ex.com/api/topics/hot.json"
                     };
        }
        else if ([apiHandle isKindOfClass:[self.latestAPIHandel class]]) {
            return @{
                     @"URLString" : @"https://www.v2ex.com/api/topics/latest.json"
                     };
        }
    
        return nil;
    }
    
    - (void )listWtihData:(NSArray *)data apiHandle:(id<APIInterface>)apiHandle
    {
        if ([apiHandle isKindOfClass:[self.hotAPIHandel class]]) {
            self.list = data;
            [self.latestAPIHandel loadData];
        }
        else if ([apiHandle isKindOfClass:[self.latestAPIHandel class]]) {
            self.list = data;
        }
    
        [self tableViewReloadData];
    }
    
    - (void )tableViewReloadData
    {
        [self.tableView reloadData];
    }
    
    - (void )didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
    }
    @end
    

    AppDelegate.m

    #import "HotAPIHandle.h"
    #import "LatestAPIHandle.h"
    
    @interface AppDelegate ()
    @property (nonatomic, strong ) HotAPIHandle *hotAPIHandle;
    @property (nonatomic, strong ) LatestAPIHandle *latestAPIHandle;
    @end
    
    @implementation AppDelegate
    
    - (BOOL )application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        self.window.backgroundColor = [UIColor whiteColor];
    
        ViewController *viewController = [[ViewController alloc] init];
    
        viewController.hotAPIHandel = self.hotAPIHandle;
        self.hotAPIHandle.callbackHandle = viewController;
        self.hotAPIHandle.paramSourceHandle = viewController;
    
        viewController.latestAPIHandel = self.latestAPIHandle;
        self.latestAPIHandle.callbackHandle = viewController;
        self.latestAPIHandle.paramSourceHandle = viewController;
    
        UINavigationController *navigationController = [[UINavigationController alloc]initWithRootViewController:viewController];
        self.window.rootViewController = navigationController;
    
        [self.window makeKeyAndVisible];
        return YES;
    }
    
    - (HotAPIHandle *)hotAPIHandle
    {
        if (!_hotAPIHandle )
        {
            _hotAPIHandle = [[HotAPIHandle alloc] init];
        }
        return _hotAPIHandle;
    }
    
    - (LatestAPIHandle *)latestAPIHandle
    {
        if (!_latestAPIHandle )
        {
            _latestAPIHandle = [[LatestAPIHandle alloc] init];
        }
        return _latestAPIHandle;
    }
    

    很多朋友问我,这样设计的优势在哪里?
    我觉得最大的优势就是:你很容易找到出错的代码。

    后记(下面以聊家常为主,没时间没兴趣的朋友请直接忽略):

    我思考过很多次,要不要继续全力推动信息。
    我当然知道,因为我的水平有限,经验有限,智商有限,在大多数情况下,我推动的信息是错的。
    但是,从我的人生经历来看,全力推,还是会更有益,更划算。

    我们很容易看到一些“不全力推”的例子。
    比如,有人会说“我今天收获很大”,然后就没有然后了,或者需要等到有人请教他,他才会继续说下去。
    比如,有人会说“你这样是错的”,然后就没有然后了,或者需要等到有人请教他,他才会继续说下去。

    我当然知道每个信息都得来不易。
    我当然知道信息差可以产生优势。
    我只是更清楚,全力去推,即使会得罪一些人,最终还是会收获更多。

    退一步讲,即使因此而失去再多的机会,我好像也不在乎。因为,对我而言,推动信息才是我一生最想要的。

    推它个天翻地覆。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2095 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:37 · PVG 08:37 · LAX 16:37 · JFK 19:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.