小明学Swift-01-基础篇

2015-10-20  本文已影响170人  TYM

简介

Swift是苹果公司推出的可用于开发Mac OS和iOS系统上的应用的专用编程语言,它相比于Objective-C(以下简称OC)语言,更加严谨,是一种强语言。


使用工具

首先,先介绍使用的工具,毕竟一个方便的工具可以大大提高效率,而这里学习Swift最快速地工具就是playground


1

playground 游乐场,可以立刻获得编译后的效果


快速入门

2

输出

常量变量

  var a1:Int = 20
let a1:Int = 20
3 5

元组

let number1:(Int,Double,CGFloat,NSInteger) = (1,1.1,1.11,2)
number1.0
number1.1
number1.2
number1.3
// 给元组的元素起名
/*
元祖的其它定义方式:指明应用元祖元素的名称
*/
let person = (name:"tym", age:18, score:100.0)
person.name
person.age
person.score
// 提取元组的数据
/*
元祖的其它定义方式:
通过指定的名称提取元祖对应的值, 会将对应位置的值 赋值给对应位置的名称
*/
let (name, age, score) = ("tym", 18, 100.0)
name
age
score
/*
如果不关心元祖中的某个值可以利用_通配符来忽略提取
*/
let (name1 , age1 , _) =  ("tym", 18, 99.8)
print(name1)
print(age1)

分支

let number = 10
//if number = 10 // Swift有效的避免了这种问题
if number == 10
{
    print(number)
}
print(age >= 18 ? "开网卡":"回家")
let score = 100
switch score
{
case 59:
    print("不及格")
case 100:
    print("满分")
default:
    print("Other")
}

var rank = "A"
switch rank{
    case "A": //相当于if
        print("优")
    case "B": // 相当于else if
        print("优")
    case "C": // 相当于else if
        print("优")
    default: // 相当于else
        print("没有评级")
}

/*
因为不能穿透所以不能这么写
var rank1 = "A"
switch rank1{
    case "A":
    case "B":
        print("优")
    case "C":
        print("优")
    default:
        print("没有评级")
}
*/

//只能这么写
var rank1 = "A"
switch rank1{
    case "A", "B": // 注意OC不能这样写
        print("优")
    case "C":
        print("差")
    default:
        print("没有评级")
}
switch score
{
case 0..<60:  // 0 ~ 59
    print("不及格")
case 60..<80:  // 60 ~ 79
    print("良好")
case 80..<100: // 80 ~ 99
    print("优秀")
default:
    print("满分")
}
// 判断元组
let point = (100, 50)
switch point
{
case (0,0):
    print("原点")
case (50,50):
    print("中点")
case (100,100):
    print("右下角")
default:
    print("Other")
}

// 值绑定
var point = (1, 10)
switch point{
    case (var x, 10): // 会将point中X的值赋值给X
        print("x= \(x)")
    case (var x, var y): // 会将point中X,Y的值赋值给X,Y
        print("x= \(x) y= \(y)")
    case var( x, y):
        print("x= \(x) y= \(y)")
    default:
        print("Other")
}

// 根据条件绑定
var point = (100, 10)
switch point{
    // 只有where后面的条件表达式为真才赋值并执行case后的语句
    case var(x, y) where x > y: 
        print("x= \(x) y= \(y)")
    default:
        print("Other")
}

可选类型

Snip20151018_11.png
7
/*
// 这样不严谨
let url = NSURL(string: "http://www.hao123.com/")
print(url)
let request = NSURLRequest(URL: url!)
*/

let url = NSURL(string: "http://www.hao123.com")
print(url)
if url != nil
{
    let request = NSURLRequest(URL: url!)
}

// 可选绑定: 如果url不为nil, 系统内部就会自动将解包之后的值赋值给temp, 并且只有temp有值时才会执行{}中的代码
// Swift开发中推荐这种写法
if let temp = url
{
    let request = NSURLRequest(URL: temp)
}

循环语句

/*:
传统for
* 基本用法和OC一致
* for后面的()可以省略
* for后面的{}不可用省略
* Swift开发中不建议使用传统for循环
*/
for var i = 0; i < 10; i++
{
    print(i)
}
// 一直循环
//for ;;
//{
//    print("---")
//}
// Swift开发者中推荐的for循环格式
for i in 0..<10
{
    print(i)
}
var number = 0
while number < 10
{
    print(number)
    number++
}
var index = 0
repeat{
    print(index)
    index++
}while index < 10

数组

// 1.遍历数组(取值)
arr[0]
for item in arr
{
    print(item)
}
// 2.添加
arr.append(3)

// 3.修改
arr[1] = 9

// 4.删除
arr.removeAtIndex(0)

// 5.合并
var arr1 = [3, 5, 7]
arr += arr1

// 6.Swift特殊
for item in arr[0..<2] // 0~1
{
    print(item)
}

//arr.removeRange(Range(start: 0, end: 2))
//arr

// 通过观察可以发现Range其实就是一个半闭区间
arr.removeRange(0..<2)
arr

arr += arr1[0..<2]

字典

var dictTest: Dictionary<String,String>
var dictTest2: [String: String]

var dict = ["name":"tym", "age":"18"]

// 企业开发中字典使用的最多的类型就是 [String: NSObject] 类型
var dict2 = ["name":"tym", "age":"18", "score":99.99]

// 取值
dict2["age"]

// 修改
dict2["age"] = 20
dict2

// 增加
dict2["rank"] = 10
dict2

// 删除
dict2.removeValueForKey("name")
dict2
// removeValueForKey返回一个可选类型, 如果字典中不存在需要删除的key, 那么返回nil并且不会执行任何操作, 如果存在则删除key对应的值, 并且返回被删除的值
var dict14 = ["name":"lnj", "age":30]
if let orignal = dict14.removeValueForKey("names")
{
    print(dict14)
    print(orignal)
}
print(dict14)

var dict15 = ["name":"lnj", "age":30]
dict15.removeAll(keepCapacity: true)

// 遍历
var dict17 = ["name":"lnj", "age":30]
for key in dict17.keys
{
    print("key = \(key)")
}

var dict18 = ["name":"lnj", "age":30]
for value in dict18.values
{
    print("value = \(value)")
}
// Swift写法
// 系统会自动将字典中的key赋值给元祖中的第一个遍历, 会自动将字典中的value赋值给元祖中的第二个遍历
for (key,object) in dict2
{
    print(key)
    print(object)
}

// 合并
var dict3 = ["name":"tym", "sex":"M", "height":179.9]
var dict4 = ["weight":120, "score":100.0]
for (key,value) in dict4
{
    dict3[key] = value
}
dict3

字符串

let str = "Hi, \0 Tym"

// 遍历字符串
for c in str.characters
{
    print(c)
}

// 字符串拼接
var str2 = "Hello,World!"
str2 += str

// 字符串格式化
let name = "tym"
let age = 18
let res = "name: \(name) , age: \(age)"

// 2015-10-19 13:55
let str3 = String(format: "%d-%02d-%02d %02d:%02d", arguments: [2015,10,19,13,55])

// 截取字符串
// 提示: 在Swift开发中, 我们经常需要将Swift的字符串转换为OC的字符串来操作, 并且Swift自身也意识到了这一点, 所以在OC字符串和Swift的字符串之间转换相当简单
let str4 = "ttyymm"
let str5: NSString = str4
str5.substringToIndex(4)
str5.substringWithRange(NSMakeRange(0, 1))

// 计算字符串长度
var stringValue = "abc李"
print(stringValue.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))
// 打印结果6, 和C语言一样计算字节数

// as 就是把什么当做什么
(str4 as NSString).substringFromIndex(2)

函数

func 函数名称(形参列表) ->返回值类型
{
        代码
}```
* Void == ()

```objc
// 1.没有参数没有返回值,没有返回值时可不写返回值
func say() -> Void
{
    print("Hi!")
}
func say1() -> ()
{
    print("Hi!")
}
say1()
func say2()
{
    print("Hi!")
}
say2()

// 2.有参数没有返回值
// Swift2.0开始, 会自动将形参列表的第二个参数名称作为标签
// Swift2.0之前是没有这个特性的, 在Swift2.0之前如果需要显示标签需要在形参名称前面加上#
func sum(num1:Int, num2:Int)
{
    print(num1 + num2)
}
sum(10, num2: 20)

// 3.没有参数有返回值
func getNumber() -> Int
{
    return 998
}
getNumber()

// 4.有参数有返回值
func sum2(num1:Int, num2:Int) -> Int
{
    return num1 + num2
}
print(sum2(11, num2: 22))
// 这里的yy就是外部参数
func sum3(num1:Int, yy num2:Int)
{
    print("num1: \(num1), num2: \(num2)")
}
//sum3(100, num2: 200)
sum3(100, yy: 300)
func joinSting(str1: String, str2: String = "是", str3: String) -> String
{
    return str1 + str2 + str3
}
joinSting("tym", str2: "不是", str3: "帅哥")
joinSting("tym", str3: "帅哥")
//func swap(a: Int, b: Int)
//{
//    let temp = a
//    a = b      // 不能修改常量
//    b = temp
//}
//func swap(var a: Int,var b: Int)
//{
//    let temp = a
//    a = b
//    b = temp
//    print("a = \(a), b = \(b)")
//}
//var a = 23
//var b = 24
//swap(&a, &b)
//
func swap1(inout a: Int,inout b: Int)
{
    let temp = a
    a = b
    b = temp
    print("a = \(a), b = \(b)")
}
var a1 = 23
var b1 = 24
print("a = \(a1), b = \(b1)")
swap1(&a1, b: &b1)
print("a = \(a1), b = \(b1)")
func sum4(numbs:Int..., temp:Int , temp2: Int) -> Int
{
    var sum = 0
    for i in numbs
    {
        sum += i
    }
    return sum + temp + temp2
}
sum4(3, temp: 10, temp2: 20)
let value = 23
func test(inout a:Int)
{
    let number = 10
    func demo()
    {
        print("\(number)", "\(a)", "\(value)")
    }
    demo()
}
var tes = 110
test(&tes)

构造函数

var name: String?
var age: Int = 0
    
    // 重写构造方法
    override init() {
        // 注意: 在构造方法中必须先初始化本类再初始化父类
        name = "tym"
        age = 18
        // 当我们重写一个类的构造方法时, 系统内部会悄悄得帮我们调用super.init()
        super.init()
    }
    
    // 自定义构造方法
    init(name: String, age: Int) {
        self.name = name
        self.age = age
        // 以下这句代码,能不写就不写
//        super.init()
    }
    
    init(dict: [String: NSObject]) {
        // 注意:Swift中如果想在构造方法中使用KVC转换模型, 必须先调用 super.init()
        // 调用 super.init()的目的主要是为了给对象分配存储空间
        super.init()
        setValuesForKeysWithDictionary(dict)
    }
    // Swift中打印对象,会调用以下属性,重写此属性,方便测试
    override var description: String {
//        return "name:\(name), age:\(age)"
        let keys = ["name","age"]
        let dict = dictionaryWithValuesForKeys(keys)
        return "\(dict)"
    }

setter、getter方法

var name: String?
        {
            // 在Swift开发中用以下两个方法代替OC中的重写setter方法
            willSet{
                print("赋值之前的调用\(newValue)")
            }
            didSet{
                print("赋值之后的调用\(oldValue)")
            }
    }
    
    var age: Int
        {
            // 在Swift中如果只重写了get方法, 那么该属性就是一个只读属性readOnly
            // 如果一个属性只重写了get方法, 我们也称之为"计算型属性", 计算型属性是不具备存储能力的
//            get{
//                return 110
//            }
            
            // 如果只是想重写一个属性的get方法, 那么可以简写
            return 120
    }

闭包

<returnType>(^<blockName>)(<parameterTypes>) = ^(<parameters>) {
<statements>
};


```objc
@implementation ViewController

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self loadData:^{
        NSLog(@"刷新UI");
    }];
}

-(void)loadData:(void (^)())finishBlock {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"%@",[NSThread currentThread]);
        NSLog(@"加载数据");
        
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"%@",[NSThread currentThread]);
            finishBlock();
        });
    });
}

@end
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        loadData ({ () -> () in
            print("刷新UI")
        })
    }
    
    func loadData(finish:()->()) {
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
            print(NSThread.currentThread())
            print("更新数据")
            
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                print(NSThread.currentThread())
                finish()
            })
        }
    }
}

loadData ({ () -> () in
print("更新UI")
})

+ 如果闭包`没有形参`, 那么in和in之前的代码都可以省略
```objc
loadData ({ 
          print("更新UI")
      })
loadData ( ){ () -> () in
          print("更新UI")
      }
loadData {
          print("更新UI")
      }

// 因为unowned相当于_unsafe_unretained,不会设置成nil,所有不用强制解包
loadData { [unowned self] () -> () in
print("刷新UI")
self.view.backgroundColor = UIColor.greenColor()
}
```


懒加载

    lazy var demoView: UIView = { 
        let v = UIView(frame: CGRectMake(10, 10, 100, 100)) 
        v.backgroundColor = UIColor.redColor() return v
    }()

gurad

guard 条件语句 else {
需要执行的语句
return
}```
- 特点:只有条件为假的时候,才会执行else中的代码,相对于if else,这个只有else
- 作用: 用于过滤数据

---

# private
- 在Swift中,添加一个属性或者方法可以在其他项目中的文件访问
- 为了封装性,可以添加private在属性或者方法或者类前,可以让该属性或者方法只能在`当前`文件中访问
- 注意:
  + 由于点击事件是由NSRunLoop发起的,并不是当前的类发起的,如果在点击方法前添加private,那么NSRunLoop无法找到该方法,会导致崩溃
  + OC是基于运行时动态派发事件的
  + Swift是编译时就已经确定了方法

---

# @objc
- 想给监听点击事件的方法加上private,并且又想让系统动态派发时找到该方法,可以在该方法前加上@objc,@objc就能让这个方法支持动态派发

```objc
@objc private func composeBtnClick()
{
}

便利构造方法

// 以下方式的确可以快速创建一个对象,但是Swift不是这种风格
    
    class func createBtn(image:String, backgroundImage:String)->UIButton
    {
        let btn = UIButton(type: UIButtonType.Custom)
        btn.setImage(UIImage(named: image), forState: UIControlState.Normal)
        btn.setImage(UIImage(named: image + "_highlighted"), forState: UIControlState.Highlighted)
        btn.setBackgroundImage(UIImage(named: backgroundImage), forState: UIControlState.Normal)
        btn.setBackgroundImage(UIImage(named: backgroundImage + "_highlighted"), forState: UIControlState.Highlighted)
        
        btn.sizeToFit()
        
        return btn
    }


/*
    定义便利构造器步骤:
    1.编写一个构造方法
    2.在构造方法前面加上 convenience
    3.在构造方法中调用当前类的其他"非便利构造器"初始化对象
    */
    convenience init(imageName: String, backImageName: String)
    {
        self.init()
        
        // 1.设置背景图片
        setBackgroundImage(UIImage(named: imageName), forState: UIControlState.Normal)
        setBackgroundImage(UIImage(named: imageName + "highlighted"), forState: UIControlState.Highlighted)
        
        // 2.设置普通图片
        setImage(UIImage(named:backImageName), forState: UIControlState.Normal)
        setImage(UIImage(named: backImageName + "highlighted"), forState: UIControlState.Highlighted)
        
        sizeToFit()
    }
上一篇 下一篇

猜你喜欢

热点阅读