如何在本地func中实现回调?

时间:2014-10-04 20:59:15

标签: swift callback

我使用类函数作为来自帮助函数的回调,每次讨论我都读过。但是,我无法访问任何iVar,如以下编译器错误所示:

enter image description here

我怀疑原因是我试图从类级函数访问iVar;这似乎是不言而喻的。

既然如此,在实例化的对象级别处理回调的正确模式是什么?

这里的 Obj-C 等同于我在Swift中尝试做的事情:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
    UIImageView *photoImageView = (UIImageView *)[cell viewWithTag:1];
    ...
    ImageDownloaderCompletionBlock completion = ^(UIImage *image, NSError *error) {                                  
        if (image) {
            photoImageView.image = image;
        } else {
            NSLog(@"%s: Error: %@", __PRETTY_FUNCTION__,
                  [error localizedDescription]);
        }
    };
    ...
    UIImage *image = [_currentImageDownloader image];                                 /

    if (image) {
        photoImageView.image = image;
    } else {
        NSURL *URL = [NSURL URLWithString: _photoInfos[_selectedItemIndex][@"url_sq"]];
        [_currentImageDownloader downloadImageAtURL:URL completion:completion];
    }

    return cell;
}

这里大致是 Swift等价的整个.swift代码,与我试图做的事情完全相同。
我已经读过我应该使用类函数来接收回调;但我认为这不允许我访问我想管理的iVars。

我更喜欢,是返回到collectionView的cellForItem ...()函数中,类似于上面显示的Objective-C范例中的内容。

import UIKit

var gPhotoData:Array<Dictionary<String,AnyObject>>?
var gDownloaders:NSMutableArray = NSMutableArray()
var currentImageDownloader:ImageDownloader?
var gSelectedItemIndex:Int?


class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        fetchFlickrPhotoWithSearchString("Ric");
    }

    // -----------------------------------------------------------------------------------------------------
    // MARK: -


    func fetchFlickrPhotoWithSearchString(searchString:String) {

        let url = getURLForString("Ric")

        let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) in
            if let httpRes = response as? NSHTTPURLResponse {
                if httpRes.statusCode == 200 {
                    let string = stringByRemovingFlickrJavaScriptFromData(data)
                    let data = string.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
                    let JSON: AnyObject? = NSJSONSerialization.JSONObjectWithData(data!, options: .AllowFragments, error: nil)

                    let rawDataDict = JSON as Dictionary<String,AnyObject>!
                    let photos: AnyObject? = rawDataDict["photos"]
                    gPhotoData = (photos!["photo"] as Array<Dictionary<String,AnyObject>>)

                    let myCount = (gPhotoData!.count - 1)

                    for index in 0...myCount {
                        let smirf = gPhotoData![index]
                        let downloader:ImageDownloader = ImageDownloader(dict: smirf)
                        gDownloaders.addObject(downloader)
                    }

                    dispatch_async(dispatch_get_main_queue(), {
                     // ...do something.
                    })

                }
            }
        }

        task.resume()

    }

    // -----------------------------------------------------------------------------------------------------
    // MARK: - Action Methods

    @IBAction func exitAction(sender: AnyObject) {
        exit(0)
    }

}

// =======================================================================================================================

extension ViewController: UICollectionViewDataSource {

    // Note: callback from a different .swift function; not shown.

    class func completion(image:UIImage) ->Void {
        // ...update ivars, etc.
        collectionView.reloadData()
    }

    // -----------------------------------------------------------------------------------------------------

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 5
    }

    // -----------------------------------------------------------------------------------------------------

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell: AnyObject = collectionView.dequeueReusableCellWithReuseIdentifier("photoCell", forIndexPath:indexPath)
        let photoImageView = cell.viewWithTag!(1) as UIImageView

        gSelectedItemIndex = indexPath.item;

        // ...do stuff....

        return cell as UICollectionViewCell

    }
}

如何实现本地(在func内)回调,类似于上面演示的ObjC等价?

0 个答案:

没有答案