【问题标题】:Event set on delegate在委托上设置的事件
【发布时间】:2012-12-18 17:26:12
【问题描述】:

我想在这里理解一些关于委托和回调的概念。基本上我正在尝试制作一个基于邮政编码的http请求。所以在发出 http-request 之前,我会调用 location-manager 并获取邮政编码,但是,在这段时间内,我必须等待异步完成该任务并获得反馈。这里的问题是,我从 location-manager 设置的委托与 http-request 类没有链接。所以,我试图了解如何将信息从委托传回 http-request。我正在研究区块,但无论如何,在区块中你是否可以等待代表的回应?或者也可以在异步任务中设置为 BOOL 属性,完成后触发请求。除了 GCD,我没有尝试过很多块,所以仍在努力解决这个问题。

欢迎在这里提出任何建议。

【问题讨论】:

    标签: iphone objective-c ios ipad cocoa


    【解决方案1】:

    这是一个草图 - (忽略错误条件和位置数据缓存问题)。这都可以在 viewController 中进行。获取邮政编码只有一个块,但如果您愿意,可以通过委托完成其余部分。

    //initialise locationManager once (eg in viewDidLoad)
    - (void) initialiseLocationManager
    {
        CLLocationManager* locationManager = [[CLLocationManager alloc] init];
        [locationManager setDelegate:self];
        [locationManager setDesiredAccuracy:kCLLocationAccuracyKilometer];
        [locationManager setDistanceFilter:500];
        self.locationManager = locationManager;
    }
    
    //[self startLocating] whenever you want to initiate another http-request
    - (void) startLocating
    {
        [self.locationManager startUpdatingLocation];
    }
    
    //locationManager delegate method
    //this will get triggered after [self startLocating] 
    //when a location result is returned
    - (void)locationManager:(CLLocationManager *)manager
         didUpdateLocations:(NSArray *)locations
    {
        CLLocation* location = [locations lastObject];
        CLGeocoder* geocoder = [[CLGeocoder alloc] init];
        [geocoder reverseGeocodeLocation:location
                       completionHandler:^(NSArray *placemarks, NSError *error){
                           CLPlacemark* placemark = [placemarks objectAtIndex:0];
                           NSString* zip = [placemark postalCode];
    
            /*
            implement your http-request code here using the zip string
            there are various ways to do this 
                        but two ways your result will arrive...
    
            1 - as a delegate callback
            so you would implement the relevant delegate method 
                        (in this same viewController) to use the result
    
            2 - as a completion block 
            so your result-using method would be that block
            */
    
        }];
        [self.locationManager stopUpdatingLocation];
    }
    

    【讨论】:

    • 这太好了,除了调用请求之外,我所做的几乎相同,我已经有一个 HttpClass,所以我通过委托调用该对象的选择器和内容返回给 httprequest 类,所以然后它调用为该特定 sel 类型构造的 httprequest。 EX: - (void)executeRequestTypes:(SEL)selector :(HttpRequest *)httpRequest 其中 httpRequest 具有保存选择器参数的属性。我只是担心它是否是一种好方法,或者是否可以使用任何其他设计模式。谢谢。
    【解决方案2】:

    在委托中,您将拥有一个符合两种协议的控制器(可能是您的视图控制器),即位置管理器的协议和 http 请求控制器定义的协议。

    视图控制器创建两个对象并将自己指定为两者的委托。
    它告诉位置管理器获取邮政编码。管理器完成后,它会在委托[self.delegate didFindZipCode:code onLocationManager: self] 上发送一个适当的委托方法。由于delegate是视图控制器,所以它实现了这个方法

    -(void)didFindZipCode:(NSString *)code onLocationManager:(MyLocationManager *)manager 
    {
        [self.httpRequestController sendZipCode:code];
    }
    

    一旦需要的数据可用,请求控制器就会以类似的方式通知视图控制器。


    实际上,blocks 会以类似的方式处理这个问题——只是没有设置委托,应该调用它,但是传递了一个代码,一旦发生事情就会调用它。

    【讨论】:

    • 嗨@viki,这确实是一个很好的概述,但是我正在研究创建块属性并为其分配变量的这种选项。不确定这是否可能?这就是我正在做的.. typedef void (^CompletionBlock)(SEL sel, ASIHttpRequest *request),我不确定我是否设置了属性,然后在位置管理器中调用关于属性变量的方法会工作?我现在对块属性有点困惑,就像它是如何工作的一样。你的想法是我的构造方式,但问题是我没有引用我想用 arg 调用的选择器
    • 你的问题很模糊,所以你为什么不发布你现在拥有的代码。顺便说一句:ASIHTTPRequest is discontinued。为什么需要跟踪需要调用的选择器?协议定义了它,并且委托人在委托上调用它。
    【解决方案3】:

    有一个很棒的库,叫做AFNetworking,它很容易实现。

    它使用块,极大地简化了类之间的数据通信(取消了委托)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多