2015-10-18 10:56:21 h454036111 阅读数 649

控制器一

import UIKit
// 第一个控制器
class ViewController: UIViewController {
    
        var aValue: Int?{
        willSet{
            print("传值成功--> \(newValue!)") //传值成功打印
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blueColor()
        
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let nv = self.navigationController{
            
            let second = SecondViewController()  //第二个控制器
            
            second.sendValue({    //回调方法
//                [unowned self]
                (i: Int) in   //闭包表达式
                self.aValue = i
            })
            nv.pushViewController(second, animated: true)
        }
        
    }

}

控制器2

import UIKit
// 第一个控制器
class ViewController: UIViewController {
    
        var aValue: Int?{
        willSet{
            print("传值成功--> \(newValue!)") //传值成功打印
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blueColor()
        
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let nv = self.navigationController{
            
            let second = SecondViewController()  //第二个控制器
            
            second.sendValue({    //回调方法
//                [unowned self]
                (i: Int) in   //闭包表达式
                self.aValue = i
            })
            nv.pushViewController(second, animated: true)
        }
        
    }

}

点击Navigation导航栏的返回按钮(相当于pop操作)运行结果:

传值成功--> 1
second 内存释放

second 立即释放的原因是因为

 let second = SecondViewController()  //第二个控制器

定义在了方法touchesBegin 方法中  局部变量的生命周期-执行完方法体结束,也就释放了 ViewController不会持有SecondViewController的实例。



我们把SecondViewController定义在全局

import UIKit
// 第一个控制器
class ViewController: UIViewController {
    
    
   <span style="color:#FF6666;"> var second: SecondViewController! //第二个控制器</span>
        var aValue: Int?{
        willSet{
            print("传值成功--> \(newValue!)") //传值成功打印
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blueColor()
        second = SecondViewController()
        
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let nv = self.navigationController{
            
            
            second.sendValue({    //回调方法
//                [unowned self]
                (i: Int) in   //闭包表达式
                self.aValue = i
            })
            nv.pushViewController(second, animated: true)
        }
        
    }

运行结果:

传值成功--> 1

为了效验发生了循环引用,我们为ViewController添加方法

     func open() {
        self.navigationController!.viewControllers = []
    }
来释放 NavigationController 对ViewController的引用

这样在内存中 只有ViewController和SecondViewController之间的相互引用。

结果是 deinit方法没有执行,发生循环引用。


解决办法:

   second.sendValue({    //回调方法
               <span style="color:#FF0000;"> [unowned self]</span>
                (i: Int) in   //闭包表达式
                self.aValue = i
            })

闭包表达式前加  [unowned self]  或者[weak self]

2016-08-02 21:26:34 Darrenzzb66 阅读数 628

一,Optional

在swift中Optional是可选类型,代表可有可无,当我们看到一个方法或者数据类型后面有?时,就代表返回的是一个可选类型。直接打印可选类型会被Optional包裹,在后面加一个!就代表一定有值,而且将其强制解析,去掉Optional包裹。


这样做的目的其实就是安全起见,因为swift是一种安全的非常语言。所以我们在使用前一般都会做判空操作

eg:   if  url  != nil  {

       let request  =  NSURLRequest( URL: url ! )

      }

另外一种就是可选绑定

eg:   if  let urlFinal = url {

       let request  =  NSURLRequest( URL: urlFinal )

      }

以上方法就是先将url中的值取出来赋值给urlFinal ,然后判断是否为空,不为空就进入{    }  里面执行代码。因为在swift中条件语句的值只能是Bool,取值只能为ture/false

二,闭包

在swift中闭包其实就是OC中的block

格式为  {   ()-> () in 

               ....

            }

第一个 ()为形参,第二个 ()为返回值,in是用于区分返回值和执行代码,如果闭包没有参数和返回值,那么in和in之前的东西都可以删除

定义一个闭包:

var  finished: () -> ()?     //这种写法是错误的,因为他代表的是返回值为可选类型

var  finished:( () -> () )?  //正确,代表闭包为可选类型


2017-12-26 19:19:28 yeyu_wuhen 阅读数 655

前言

本章内容完全是描写苹果新语言的基础练习,对于初学者来说是非常好用,好学、升级了编辑器Xcode9快速体验Swift4语法
print("Hello, world!")就是这么简单的打印
该内容基于语法教程,更多内容可以去Develpoer去看API

内容概括

  1. 简单值
  2. 控制流
  3. 函数和闭包
  4. 对象和类
  5. 枚举和结构体
  6. 协议和扩展
  7. 错误处理
  8. 泛型
简单值
  • 使用 let 来声明常量,使用 var 来声明变量。
var myVariable = 42
myVariable = 50
let myConstant = 42
  • 不用明确地声明类型,声明的同时赋值的话,编译器会自动推断类型
let implicitInteger = 70
let implicitDouble = 70.0
let explicitDouble: Double = 70
  • 值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换
let label = "The width is"
let width = 94
let widthLabel = label + String(width)
  • 有一种更简单的把值转换成字符串的方法:把值写到括号中,并且在括号之前写一个反斜杠
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."
  • 使用方括号 [] 来创建数组和字典,并使用下标或者键(key)来访问元素。最后一个元素后面允许有个逗号。
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
shoppingList[1] = "bottle of water"

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"
控制流
  • 使用 if 和 switch 来进行条件操作,使用 for-in、 for、 while 和 repeat-while 来进行循环
let individualScores = [75, 43, 103, 87, 12]
var teamScore = 0
for score in individualScores {
    if score > 50 {
        teamScore += 3
    } else {
        teamScore += 1
    }
}
print(teamScore)
  • 使用 while 来重复运行一段代码直到不满足条件。循环条件也可以在结尾,保证能至少循环一次。
var n = 2
while n < 100 {
    n = n * 2
}
print(n)

var m = 2
repeat {
    m = m * 2
} while m < 100
print(m)
  • 可以在循环中使用 ..< 来表示范围。
var total = 0
for i in 0..<4 {
    total += i
}
print(total)
函数和闭包
  • 闭包和函数是一个重点,也是难点,比较难学
  • 简单函数比如
func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet(person:"Bob", day: "Tuesday")
  • 使用元组来让一个函数返回多个值。该元组的元素可以用名称或数字来表示
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
    var min = scores[0]
    var max = scores[0]
    var sum = 0

    for score in scores {
        if score > max {
            max = score
        } else if score < min {
            min = score
        }
        sum += score
    }

    return (min, max, sum)
}
let statistics = calculateStatistics(scores:[5, 3, 100, 3, 9])
print(statistics.sum)
print(statistics.2)
对象和类
  • 使用 class 和类名来创建一个类。类中属性的声明和常量、变量声明一样,唯一的区别就是它们的上下文是类。同样,方法和函数声明也一样。
class Square: NamedShape {
    var sideLength: Double

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }

    func area() ->  Double {
        return sideLength * sideLength
    }

    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()
枚举和结构体
  • 使用 enum 来创建一个枚举。就像类和其他所有命名类型一样,枚举可以包含方法
enum Rank: Int {
    case ace = 1
    case two, three, four, five, six, seven, eight, nine, ten
    case jack, queen, king
    func simpleDescription() -> String {
        switch self {
        case .ace:
            return "ace"
        case .jack:
            return "jack"
        case .queen:
            return "queen"
        case .king:
            return "king"
        default:
            return String(self.rawValue)
        }
    }
}
let ace = Rank.ace
let aceRawValue = ace.rawValue
协议和扩展
  • 类、枚举和结构体都可以实现协议。
class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += " Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
错误处理
do {
    let printerResponse = try send(job: 1440, toPrinter: "Gutenberg")
    print(printerResponse)
} catch PrinterError.onFire {
    print("I'll just put this over here, with the rest of the fire.")
} catch let printerError as PrinterError {
    print("Printer error: \(printerError).")
} catch {
    print(error)
}
泛型
  • 在尖括号里写一个名字来创建一个泛型函数或者类型。
func repeatItem<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
    var result = [Item]()
    for _ in 0..<numberOfTimes {
        result.append(item)
    }
    return result
}
repeatItem(repeating: "knock", numberOfTimes:4)
2016-08-12 23:57:41 angcyo 阅读数 2710

在IOS 8.0之后, UIAlertView 和 UIActionSheet 已经被废弃了. 取而代之的是UIAlertController

阅读之前,你需要具有Swift语法基础,至少要能看懂闭包以及结尾闭包.


下图是UIAlertControllerStyle.Alert (UIAlertView)样式的截图:
这里写图片描述

下图就是UIAlertControllerStyle.ActionSheet (UIActionSheet)样式的截图:
这里写图片描述

看了效果图,接下来就上代码了.

//第一个参数是标题,第二个参数是消息内容,第三个参数就是上2张图中的样式,随便选一个.
let alertViewController = UIAlertController(title: "title", message: "message", preferredStyle: .ActionSheet)

//如果没有调用addAction方法, 对话框也是会显示的.但是没有可以点击的按钮.
alertViewController.addAction(UIAlertAction(title: "title1", style: .Cancel, handler: { action in print("onAction") }))

//UIAlertAction的第二个参数是 按钮的样式(取消(粗体显示),消极(红色显示),正常)3种样式. 
//第三个参数是一个函数类型的参数. 表示点击按钮之后的调用的方法.
alertViewController.addAction(UIAlertAction(title: "title2", style: .Default, handler: { action in
        print("1")
        print("2")
        })
    )
alertViewController.addAction(UIAlertAction(title: "title3", style: .Default) { action in
        print("11")
        print("22")
        }
    )
alertViewController.addAction(UIAlertAction(title: "title4", style: .Destructive, handler: nil))
//显示对话框
self.presentViewController(alertViewController, animated: true, completion: nil)

这里写图片描述

这里写图片描述


向对话框中添加文本框:效果图
这里写图片描述

文本框可以添加多个

alertViewController.addTextFieldWithConfigurationHandler({ textField in print(textField.text);textField.text = "angcyo1" })
alertViewController.addTextFieldWithConfigurationHandler({ textField in print(textField.text);textField.text = "angcyo2" })
alertViewController.addTextFieldWithConfigurationHandler({ textField in print(textField.text);textField.text = "angcyo3" })

获取文本框的内容:

alertViewController.addAction(UIAlertAction(title: "title3", style: .Default) { action in
print("textFields:\(alertViewController.textFields?[0].text)")
print("textFields:\(alertViewController.textFields![1].text)")
for textFields in alertViewController.textFields! {
    print("textFields:\(textFields.text)")
    }
  }
)

需要注意的是: 文本框只能在 UIAlertControllerStyle.Alert 样式下,才能添加.否则会报异常.


至此: 文章就结束了,如有疑问: QQ群 Android:274306954 Swift:399799363 欢迎您的加入.

2016-01-28 09:01:59 milk_1477260157 阅读数 80

Swift基本语法(强类型语言)


语句结束 —>;

不需要分号回车即可,多语句并列时,可使用

alloc init —> ()

alloc initWithXXX —> (XXX: )

类函数 —> .

可以省略self. 最好不要加闭包中需要self. 

枚举类型 —> 分开写.

NSLog打印 —> print 带换行 

selection —> “xxx”

字符串拼接 —> ...\(字符串)

方法:

func click(sender:UIButton){

        print("点我了---\(str)")

}


1.常量|变量:

let —> 常量尽量用let

var —> 变量必要修改时再用var

自动推导右侧类型任何时候都不会做隐式转换必须是相同类型进行计算类型不同需要强转

强转 —> 类型()

浮点类型默认 —> Double

整数类型默认 —> Int


*可选项 Optional一个变量可为本身类型也可为nil

eg. let x: Double = 20

      print(x + 1.5)

      let y: Int? // 可以是整数也可以是nil, 如果是变量默认是nil

      var z: Int? = 10

可选项不能直接计算—> 强行解包(unwrapping), 程序员承诺一定有值如果没有就崩

构造函数有? —> 不一定能创建出对象

  没有? —> 一定有值, 没有就崩

提示: 可选项注意思考为什么?


2.控制流:

if

if 变化:

-1. 没有(), 必须有{}

格式: if 条件 {}

-2. 没有非零即真只有truefalse

-3. 三目很常用


if let 用法: 分支内部处理

if let name = oName {

print("xxx" + name)

}

// 多值判断

if let name = oName, age = oAge {

print("xxx" + name + age)

}


guard let … else … 用法: 分支外部处理

与if let相反, 保证一定有值

guard let age = oAge else {

print("age为nil")

}


swith 变化:

-1.不需要break, 必须涵盖所有条件每个case至少包含一条语句无内容用break代替

-2.任意数据类型可判断

-3.case之间不会穿透多指用,分隔

-4.定义变量不用{}分隔作用域


3.字符串:

String 用法:

-1.拼接 —> \(变量名)

-2.String类型 —> 结构体量级更轻

-3.支持直接遍历

-4.字符串长度 —> strin.characters.count

-5.格式化 —> String(format: "%d", arguments:[数组])

      String(format: "%d", 参数,…)

-6.取子串: NSString

let str = "xxxnihao"

let s1 = (str as NSString).substringWithRange(NSMakeRange(n, n))

// 变化最频繁

let s2 = str.substringFromIndex("1234".endIndex) // 4个字符长开始取, 1234只为占位

// ihao

// 指定范围 ..<

// advancedBy 正数向右移动负数向左移动

let startIndex = str.startIndex.advancedBy(2)

let endIndex = str.endIndex.advancedBy(-2)

// 掐头去尾

let range = startIndex..<endIndex

let s3 = str.substringWithRange(range)

// xnih


4.循环:

for

for 变化:

-1.没有()


for in 变化:

-1.范围注意不要多加空格

for i in 0..<9 { // 0~8}

for i in 09 { // 0~9} // 0…9 == 0..<10


5.集合:

数组:

-1.[] 定义:

[String] [NSObject]

let array = ["xxx", "xxx"]

let array = ["xxx", "xxx", 29]

-2.可直接存基本数据类型

-3.结构体同样需要包装成 NSValue —> NSValue(CGPoint: CGpoint(x:10, y:29))

-4.可变 | 不可变: var | let

-5.指定类型

var array: [NSObject] = []

var array: [AnyObject] = [] // 范围更大没有任何父类

-6.遍历:

for s in array {

print(s)

}

-7.增删改查:

: array.append()

: array.removeFirst()

      array.removeLast()

      array.removeAll(keepCapacity: true) // 保持容量 

: array[index] = "xxx" // 下标获取元素


数组容量: array.capacity

分配空间: array = [String]()

-8.合并:

var array = []

let array2 = []

// array2 合并到array

array += array2

// 注意合并时数组类型必须保持一致


字典:

-1.定义: ["ddd": "xxx", "ggg": 19]

-2.类型: [String: NSObject] | 

 [String: AnyObject类型最多网络获取json有要求, key必须是String

-3.可变 | 不可变: var | let

可变如果key存在覆盖不存在新增

-4.遍历:

for (key, value) in dict {

print("k:\(key)——v:\(value)")

}

-5.增删改查:

: dict["nnn"] = "xxx"

-6.合并:

var dict = []

let dict2 = []

// dict2 合并到dict, 如果key存在覆盖不存在新增

for (key, value) in dict2 {

dict[key] = value

}


6.函数:

-1.格式: func 函数名(形参列表) -> 返回值类型 {}

func sum(x: Int, y: Int) -> Int {

return x+y

}

调用: sum(29, y: 39) // 默认第一个参数名可省略

-2.外部参数:

func sum(num1 x: Int, num2 y: Int) -> Int {

return x+y

}

调用: sum(num1: 29, num2: 39) // 方便调用者明确各参数的语义

-3.无返回值格式:

1>啥都不写

2> Void

3> ()

eg.

func demo1 {

print("")

}

func demo2 -> Void {

print("")

}

func demo3 -> () {

print("")

}


7.闭包:(类似block)

-1.定义所有代码都放在{参数 返回值 执行代码}

有参有返回:

格式: { (外部参数 形参列表) -> 返回值 in // 执行代码}

let sumFunc = {

(num1 x: Int, num2 y: Int) -> Int

in // 用于区分函数定义和执行代码

return x+y

}

// 外部参数很重要能够有智能提示

调用: sum(num1: 29, num2: 39)


无参无返回:

格式: () -> ()

let demo = { // 代码 }

调用: demo()


函数本身就可做参数传递

let sumFunc = sum

let r = sumFunc(10, y: 29) // r -> Int类型


func sum(num1 x: Int, num2 y: Int) -> Int {

return x+y

}


-2.应用场景异步加载网络数据完成回调

block对比:


-3.尾随闭包

闭包参数是函数的最后一个参数 -> 

函数的)结束可以前置到倒数第二个参数的末尾

最后一个,分隔符可省略

-4.简化闭包无参无返回可省略


8.解除循环引用(Block):









Swift 初见

阅读数 2

闭包的一个坑

阅读数 189

没有更多推荐了,返回首页