swift Вконечномсчетеярешил,чтоэтопростаярекурсия。 Надругихязыкахрекурсиюяреализовывал。 Пробуюнасвифт

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了swift Вконечномсчетеярешил,чтоэтопростаярекурсия。 Надругихязыкахрекурсиюяреализовывал。 Пробуюнасвифт相关的知识,希望对你有一定的参考价值。

//
//  Model.swift
//  KidSpace
//
//  Created by October Hammer on 4/19/17.
//  Copyright © 2017 Ocotober Hammer. All rights reserved.
//

import Foundation
import Parse
import ParseUI
import Bolts

//Это нужно чтобы зарегистрировать унаследованный от PFOject класс
extension Category: PFSubclassing {
	static func parseClassName() -> String {
		return "Category"
	}
}


//Создаю класс, унаследованный от PFObject
class Category: PFObject {
//class Category {
	//	@NSManaged public private(set) var objectId: String?
	@NSManaged public private(set) var name: String?
	@NSManaged public private(set) var picture: PFFile?
	@NSManaged public private(set) var pictureData: Data?//хочу хранить данные для картинки в этом свойстве
	@NSManaged public private(set) var url: String?
	@NSManaged public private(set) var parent: Category?
	
	init(_ id: String, name: String) {
		super.init()
		self.objectId = id
		self.name = name
	}
	
	//метод, которым получаю данные из PFFile
	func retrieveImage(from: PFFile, result: @escaping (_ imageData: Data?) -> Void ) {
		from.getDataInBackground(block: {(imageData: Data?, error: Error?) -> Void in
			if error == nil {
				if let imageData = imageData {
					if let imageFile = UIImage(data: imageData) {
						print("I've got a picture for \(self.objectId), size: \(imageData.count)")
						imageFile.write(to: self.objectId!)// Записываю полученное изображение в файл
					}
					result(imageData)//И вызываю замыкание с результатом, чтобы присвоить полученные данные уже вне этого метода
				}
			} else {
				print("☠️      \(error?.localizedDescription ?? "there is some error")")
				result(nil)
			}
		})
	}

	
	static func selectRootElements(_ compleationHandler: @escaping ((_ categorySelection: [Category]?) -> Void)) {
		var catSelection: [Category]? = []//Это у меня локальная переменная, в которую я буду скалдывать свою выборку
		
		func completionInMainQ()  {
			//После того, как я получил все нужные элементы, уже с картинками, я хочу их вернуть во ВьюКонтроллер:
			DispatchQueue.main.async {
				compleationHandler(catSelection)
			}
		}
		
		//Конструкции ниже - для реализации рекурсивного замыкания
		typealias CBType = (Int, [PFObject]) -> Void //функциональный тайпалиас, чтобы строчкой ниже объявить
		var getDataForItem: CBType? //переменную Опшионал этого типа, которая в свою очередь нужна, чтобы не поймать ошибку 'Variable used within its own initial value' или еще одну
		
		
		let placeHolder: CBType = { (_ currentIndex: Int, pfCategories: [PFObject]) -> Void in
			if pfCategories.count > currentIndex {
				let category = Category(pfCategories[currentIndex].objectId!, name: pfCategories[currentIndex]["name"] as! String)//по сути я создаю новый инстанс
				category.url = pfCategories[currentIndex]["URL"] as? String
				if let picture = pfCategories[currentIndex].value(forKey: "picture") as? PFFile {
					category.retrieveImage(from: picture) {(_ imageData: Data?) -> Void  in
						category.pictureData = imageData//вот они, данные картинки
						catSelection?.append(category)//добавил
						let nextIndex = currentIndex + 1
						if let getDataForNextItem = getDataForItem { // так как переменная - опшионал типа, то анврапим ее
							getDataForNextItem(nextIndex, pfCategories) //и вызываем для следующего элемента
						}
					}
				}
			} else {
				completionInMainQ()
			}
		}
		// переменной, которую мы сначала объявили как опшионал, назначаем наше замыкание, которое получает картинку для и-того элемента массива
		getDataForItem = placeHolder
		
		
		//А вот дальше код
		let query = PFQuery(className: "category")
		query.whereKeyDoesNotExist("parentID")// Получаю только корневые элементы, то есть те, у которых ссылка на родителя - пустая, их у меня в приложении - 8 записей
		query.findObjectsInBackground {(pfCategories: [PFObject]?, error: Error?) in
			if error == nil {
				if let pfCategories = pfCategories {
					print("Successfully retrieved \(pfCategories.count) categories.")
					//for (index, everyCategory) in pfCategories.enumerated() {
					var currentIndex = 0
					placeHolder(currentIndex, pfCategories)
				}
			}
		}
	}

	
	
	func getImage() -> UIImage? {
		let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
		let filePath = documentsURL.appendingPathComponent("\(self.objectId).png").path
		if FileManager.default.fileExists(atPath: filePath) {
			return UIImage(contentsOfFile: filePath)
		}
		return nil
	}
	


	

}


extension UIImage {
	func write(to: String){
		do {
			let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
			let fileURL = documentsURL.appendingPathComponent("\(to).png")
			if let pngImageData = UIImagePNGRepresentation(self) {
				try pngImageData.write(to: fileURL, options: .atomic)
			}
		} catch { }
	}
}

















以上是关于swift Вконечномсчетеярешил,чтоэтопростаярекурсия。 Надругихязыкахрекурсиюяреализовывал。 Пробуюнасвифт的主要内容,如果未能解决你的问题,请参考以下文章

php Автоматическаяочисткатегированногокеша添加了

python Естьдваспискаразнойдлины。 Впервомсодержатсяключи,авовторомзначения。 Напишитефункцию,котораясо

text js,jquery - обрежемлишнийтекствкарточкекурсовипоставиммноготочие

php WP All Import - Автоматическаявставкашорткодагалереи,неудалосьдоконца。 Нужнообновлятьвручную

La Sylphide 仙女

php WordPressназаглушки的Заменяетбитыессылкинакратинки。 Удобно,напримернатестовомсайте,чтобынеперенос