我使用类函数作为来自帮助函数的回调,每次讨论我都读过。但是,我无法访问任何iVar,如以下编译器错误所示:
我怀疑原因是我试图从类级函数访问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等价?