4.Swift初探-2048小游戏中的问题
来源:互联网 发布:淘宝盖楼是什么 编辑:程序博客网 时间:2024/04/29 06:17
最近工作不是很忙,就继续学习swift,想着干学习语法提高太慢,就试着用swift写了一个2048小游戏,中间遇见的一些问题在这里记录一下:
1、自定义类
首先自定义类就花费了很大的力气,主要是因为swift自定义类时严格控制了初始化,我想自定义一个继承自UIView的类,首先必须写这个函数:
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }require关键字表明如果子类需要添加异于父类的初始化方法时,必须先要实现父类中使用
required
修饰符修饰过的初始化方法,并且也要使用required
修饰符而不是override
。如果子类中不需要添加任何初始化方法,我们则可以忽略父类的required
初始化方法:在Objective-C中,init方法是非常不安全的:没有人能保证init只被调用一次,也没有人保证在初始化方法调用以后,实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的话,还可能会造成各种问题。虽然Apple也明确说明了不应该在init中使用属性来访问,但这并不是编译器强制的,因此还是会有很多开发者犯这样的错误。
所以Swift有了超级严格的初始化方法。一方面,Swift强化了designated初始化方法的地位。Swift中不加修饰的init方法都需要在方法中保证所有非Optional的实例变量被赋值初始化,而在子类中也强制 (显式或隐式地)调用super版本的designated初始化,所以无论如何走何种路径,被初始化的对象总是可以完成完整的初始化的。以下是我的初始化方法:
init() { self.number = 2 self.frameNumber = 16 for lineNumber in 0...3 { for columnNumber in 0...3 { let cubX = CGFloat(columnNumber)*(cubWidth+space)+space let cubY = CGFloat(lineNumber)*(cubWidth+space)+space let cubFrame:CGRect = CGRectMake(cubX, cubY, cubWidth, cubWidth) self.frameArray.append(cubFrame) } } super.init(frame:CGRectMake(0, 0, cubWidth, cubWidth)) self.label.text = "2" self.label.font = UIFont.init(name:label.font.fontName, size: 70) self.label.textAlignment = NSTextAlignment.Center self.label.backgroundColor = UIColor.whiteColor() self.addSubview(self.label) } convenience init(number:Int) { self.init() self.number = number self.label.text = "\(number)" }与designated初始化方法对应的是在init前加上convenience关键字的初始化方法。这类方法是Swift初始化方法中的“二等公民”,只作为补充和提供使用上的方便。所有的convenience初始化方法都必须调用同一个类中的designated初始化完成设置,另外convenience的初始化方法是不能被子类重写或从子类中以super的方式被调用的。
只要在子类中实现重写了父类convenience方法所需要的init方法的话,我们在子类中就也可以使用父类的convenience初始化方法了。
因此进行一下总结,可以看到初始化方法永远遵循以下两个原则:
- 初始化路径必须保证对象完全初始化,这可以通过调用本类型的designated初始化方法来得到保证;
- 子类的designated初始化方法必须调用父类的designated方法,以保证父类也完成初始化。
对于某些我们希望子类中一定实现的designated初始化方法,我们可以通过添加required关键字进行限制,强制子类对这个方法重写实现。这样的一个最大的好处是可以保证依赖于某个designated初始化方法的convenience一直可以被使用。
2.属性成员的set和get方法
在OC中,我们可以重写 set和get方法去满足我们的需求,在swift中,这方面分得更加细致。首先把属性进行了分类,分为了存储属性和计算属性。对于存储属性,只需要单纯的 存储数据,所以不需要重写get和set方法。而对于计算属性,就是需要通过计算来设置值的,需要重写,具体形式如下:
var perimeter: Double { get { return 3.0 * sideLength } set { sideLength = newValue / 3.0 } }
当我们需要在外部给属性成员赋值后进行一些操作的话,我们可以使用willSet和didSet,在代码中我的使用如下:
var number:Int { didSet { label.text = "\(self.number)" } }
3.强制类型转换和数组排序
在swift中强制类型转换通过类似这种形式:Int(要转化的变量),但如果你要将父类对象强转为子类对象的话,需要使用as,具体如下:
for cub in self.gameBackGround.subviews{ if (cub is CYLCubView) { subViewArray.append(cub as! CYLCubView) }}
如果是从子类转化而来的父类对象,则一定可以转化回去,使用as! ,如果不确定,则使用as
在swift中使用.sort进行排序,这里用到了闭包,还有一点不太理解,看一下别人的说法,讲得很清晰:
直接贴代码,不过多解释
//这是我们的modelclass imageFile { var fileName = String() var fileID = Int()}
//使用var images : [imageFile] = []images.sort({ $0.fileID > $1.fileID })
下面是闭包的进阶使用
// 一般的代码形式images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })// 省略(->)的形式images.sort({ image1, image2 in return image1.fileID > image2.fileID })// 带返回值的简单闭包形式images.sort({ image1, image2 in image1.fileID > image2.fileID })// 隐含参数的形式images.sort({ $0.fileID > $1.fileID })// 以下结果都是相同,只是书写形式不同images = images.sorted({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })images = images.sorted({ image1, image2 in return image1.fileID > image2.fileID })images = images.sorted({ image1, image2 in image1.fileID > image2.fileID })images = images.sorted({ $0.fileID > $1.fileID })
//swift标准库sort(&images, { (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })sort(&images, { image1, image2 in return image1.fileID > image2.fileID })sort(&images, { image1, image2 in image1.fileID > image2.fileID })sort(&images, { $0.fileID > $1.fileID })//使用方法images = sorted(images, { (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })images = sorted(images, { image1, image2 in return image1.fileID > image2.fileID })images = sorted(images, { image1, image2 in image1.fileID > image2.fileID })images = sorted(images, { $0.fileID > $1.fileID })
在项目中我的用法:array1.sortInPlace({$0.frameNumber < $1.frameNumber})根据数组中对象的frameNumber属性从小到大进行排序
4.宏定义和懒加载
lazy var maskView:UIView? = { let maskView = UIView.init(frame: CGRectMake(0, 0, screenWidth, screenHeight)) maskView.backgroundColor = UIColor.blackColor() maskView.alpha = 0.9 return maskView }()
- 4.Swift初探-2048小游戏中的问题
- 初探swift
- swift初探
- swift 开灯小游戏
- swift 拼图小游戏
- iOS swift 2048小游戏开发教程(一)
- 初探GObject中的interface'接口'问题
- 操作系统初探-同步中的互斥问题
- Swift初探一
- swift学习资料初探
- Swift编程语言初探
- swift语言初探1
- Swift 2.0初探
- swift语法初探 -- 1
- 初探 Swift SPriteKit
- 1.Swift初探
- Swift学习 PlayGround初探
- Swift 2.0初探
- iOS开发 -- 利用dispatch_once创建单例
- HDU 1846 Brave Game(巴什博奕)
- 常用的hibernate注解标签
- Git命令总结
- [Unity]关于多角色自由切换主操作角色的问题
- 4.Swift初探-2048小游戏中的问题
- Scrollview嵌套Listview出现的问题
- 通过时间戳防止scroll 反复触发
- ASP代码开发规范
- android访问数据库时报runtiameException,和空指针异常
- iOS UIlabel sizeToFit失效的问题
- UE3 基本的分析及优化技术
- 黑马程序员——反射
- 黑马程序员——图形化界面