anyobject swift

2017-12-29 17:13:44 u012189584 阅读数 627
AnyObject 可以代表任何class类型的实例
Any 可以表示任意类型,甚至包括方法(func)类型
一、AnyObject 。
写过Objective-C的朋友会知道在Objective-C中有一个叫做id的类型。编译器不会对向声明的为id的变量进行类型检查,它可以表示任意类的实例。在Cocoa框架中不很多地方都使用了id来进行像参数传递和方法返回这样的工作,这是Objective-C动态特性的一种表现。现在的Swift最主要的用途依然是使用Cocoa框架进行app开发,因此为了与Cocoa架构协作,将原来id的概念使用了一个类似的,可以代表任意class 类型的AnyObject来进行替代。
id与AnyObject有本质的区别。在Swift中编译器不仅不会对Anyobject实例的方法调用做出检查,甚至对于AnyObject 的所有方法调用都会返回Optional 的结果。这虽然是符合Anyobject中的理念,但是在Swift环境下使用起来就非常麻烦,也很危险。应该选择的做法是在使用时先确定Anyobject真正的类型并进行转换以后再进行调用。
AnyObject的定义,可以发现它其它就是一个接口: 特别之处在于,所有的class都隐式地实现了这个接口,这也是AnyObject 只适用于class类型 的原因。
二、Any
Swift中所有的基本类型,包括Array 和Dictionary 这些传统意义上会是class的东西,统统都是struct类型,并不能由AnyObject来表示 ,于是Apple提出一个更为特殊的Any。除了class 以外,它还可以包括struct 和enum在内的所有类型。
总结:
AnyObject 可以代表任何class类型的实例
any :表示数据类型
2017-06-04 09:43:09 feosun 阅读数 1899

1. AnyObject :代表任何class类型的对象实例。

class Man{
}

class Woman{
}

let man = Man()
let woman = Woman()
var arr:[AnyObject] = [man,woman]

for people in arr {
    if let m = people as? Man {
        println("这是个男人")
    }else if let w = people as? Woman {
        println("这是个女人")
    }
}

2. Any :范围更广,代表除函数外任何类型的实例。不仅包含object对象,还包含基本类型。

class Man{
}

class Woman{
}

var arr:[Any] = [Any]()
arr.apppend(1)
arr.append("hangge.com")
arr.append(Man())
arr.append(Woman())

for any in arr {
    switch any {
        case let any as Int:
            println("这是个Int类型")
        case let any as String:
            println("这是个String类型")
        case let any as Man:
            println("这是个男人类型")
        case let any as Woman:
            println("这是个女人类型")
        default:
            println("这是个未知类型")
    }
}

3. AnyClass是AnyObject.Type的别名而已。

看一下AnyClass的定义: typealias AnyClass = AnyObject.Type

2019-09-18 16:51:38 songzhuo1991 阅读数 144

关键字Any、AnyObject

  • Swift提供了两种特殊的类型:Any、AnyObject

Any:可以代表任意类型(枚举、结构体、类,也可以包括函数类型)
范围更广,代表除函数外任何类型的实例。不仅包含object对象,还包含基本类型。
AnyObject:可以代表任意类类型(在协议后面写上:AnyObject代表只有类能遵守这个协议)
代表任何class类型的对象实例


关键字is、as?、as!、as

  • Swift提供了两种特殊的类型:Any、AnyObject
  • is用来判断是否为某种类型,as用来做强制类型转换
        protocol Runnable { func run() }
        class Person {}
        class Student : Person, Runnable {
            func run() {
                print("student run")
            }
            func study() {
                print("student study")
            }
        }
    var stu: Any = 10
    print(stu is Int) //true
    stu = "Jack"
    print(stu is String) //true
    stu = Student()
    print(stu is Person) //true
    print(stu is Student) //true
    print(stu is Runnable) //true
    var stu: Any = 10
    (stu as? Student)?.study() //没有调用study
    stu = Student()
    (stu as? Student)?.study() //student study
    (stu as! Student).study()  //student study
    (stu as? Runnable)?.run()  //student run
    var data = [Any]()
    data.append(Int("123") as Any)
    var d = 10 as Double
    print(b)  //10.0在这里插入代码片

关键字X.self、X.Type、AnyClass

  • X.self是一个元类型(metadata)的指针,metadata存放着类型相关信息
  • X.self属于X.Type类型
class Person {}
class Student : Person {}
var perType: Person.Type = Person.self
var stuType: Student.Type = Student.self
perType = Student.self
var anyType: AnyObject.Type = Person.self
anyType = Student.self

public typealias AnyClass = AnyObject.Type
var anyType2: AnyClass = Person.self
anyType2 = Student.self
var per = Person()
var perType = type(of:per)  //Person.self
print(Person.self == type(of:per))  //true

应用:父类必须用required修饰初始化器,保证子类也有对应的初始化器

class Animal { required init() {} }  
class Cat : Animal {}
class Dog : Animal {}
class Pig : Animal {}
func create(_ clses: [Animal.Type]) -> [Animal] {
    var arr = [Animal]()
    for cls in clses {
        arr.append(cls.init())
    }
    return arr
}
print(create([Cat.self, Dog.self, Pig.self]))

runtime:swift还有一个隐藏的基类:Swift_SwiftObject

class Person {}
class Student : Person {}
class_getInstanceSize(Person.self)
class_getSuperclass(Person.self)  //
class_getSuperclass(Student.self)

关键字Self

  • Self一般用作返回值类型,限定返回值跟方法调用者必须是同一类型(也可以作为参数类型)
protocol Runnable {
    func test() -> Self
}
class Person : Runnable {
    required init() {}
    func test() -> Self { type(of:self).init() }
}
class Student: Person { }

var p = Person()
print(p.test()) //Person
var stu = Student()
print(stu.test()) //Student

如果Self用在类中,要求返回时调用的初始化器是required

2017-09-26 15:12:52 sun_cui_hua 阅读数 1532

转载:http://swifter.tips/any-anyobject/
Any 和 AnyObject 是 Swift 中两个妥协的产物,也是很让人迷惑的概念。在 Swift 官方编程指南中指出

AnyObject 可以代表任何 class 类型的实例
Any 可以表示任意类型,甚至包括方法 (func) 类型

先来说说 AnyObject 吧。写过 Objective-C 的读者可能会知道在 Objective-C 中有一个叫做 id 的神奇的东西。编译器不会对向声明为 id 的变量进行类型检查,它可以表示任意类的实例这样的概念。在 Cocoa 框架中很多地方都使用了 id 来进行像参数传递和方法返回这样的工作,这是 Objective-C 动态特性的一种表现。现在的 Swift 最主要的用途依然是使用 Cocoa 框架进行 app 开发,因此为了与 Cocoa 架构协作,将原来 id 的概念使用了一个类似的,可以代表任意 class 类型的 AnyObject 来进行替代。

但是两者其实是有本质区别的。在 Swift 中编译器不仅不会对 AnyObject 实例的方法调用做出检查,甚至对于 AnyObject 的所有方法调用都会返回 Optional 的结果。这虽然是符合 Objective-C 中的理念的,但是在 Swift 环境下使用起来就非常麻烦,也很危险。应该选择的做法是在使用时先确定 AnyObject 真正的类型并进行转换以后再进行调用。

假设原来的某个 API 返回的是一个 id,那么在 Swift 中现在就将被映射为 AnyObject? (因为 id 是可以指向 nil 的,所以在这里我们需要一个 Optional 的版本),虽然我们知道调用来说应该是没问题的,但是我们依然最好这样写:

func someMethod() -> AnyObject? {
// ...

// 返回一个 AnyObject?,等价于在 Objective-C 中返回一个 id
return result
}

let anyObject: AnyObject? = SomeClass.someMethod()
 if let someInstance = anyObject as? SomeRealClass {
// ...
// 这里我们拿到了具体 SomeRealClass 的实例

someInstance.funcOfSomeRealClass()
}

如果我们注意到 AnyObject 的定义,可以发现它其实就是一个接口:

 protocol AnyObject {
  }

特别之处在于,所有的 class 都隐式地实现了这个接口,这也是 AnyObject 只适用于 class 类型的原因。而在 Swift 中所有的基本类型,包括 Array 和 Dictionary 这些传统意义上会是 class 的东西,统统都是 struct 类型,并不能由 AnyObject 来表示,于是 Apple 提出了一个更为特殊的 Any,除了 class 以外,它还可以表示包括 struct 和 enum 在内的所有类型。

为了深入理解,举个很有意思的例子。为了实验 Any 和 AnyObject 的特性,在 Playground 里写如下代码:

import UIKit

 let swiftInt: Int = 1
let swiftString: String = "miao"

var array: [AnyObject] = []
array.append(swiftInt)
array.append(swiftString)

我们在这里声明了一个 Int 和一个 String,按理说它们都应该只能被 Any 代表,而不能被 AnyObject 代表的。但是你会发现这段代码是可以编译运行通过的。那是不是说其实 Apple 的编程指南出错了呢?不是这样的,你可以打印一下 array,就会发现里面的元素其实已经变成了 NSNumber 和 NSString 了,这里发生了一个自动的转换。因为我们 import 了 UIKit (其实这里我们需要的只是 Foundation,而在导入 UIKit 的时候也会同时将 Foundation 导入),在 Swift 和 Cocoa 中的这几个对应的类型是可以进行自动转换的。因为我们显式地声明了需要 AnyObject,编译器认为我们需要的的是 Cocoa 类型而非原生类型,而帮我们进行了自动的转换。

在上面的代码中如果我们把 import UIKit 去掉的话,就会得到无法适配 AnyObject 的编译错误了。我们需要做的是将声明 array 时的 [AnyObject] 换成 [Any],就一切正确了。

let swiftInt: Int = 1
let swiftString: String = "miao"

var array: [Any] = []
array.append(swiftInt)
array.append(swiftString)
array

顺便值得一提的是,只使用 Swift 类型而不转为 Cocoa 类型,对性能的提升是有所帮助的,所以我们应该尽可能地使用原生的类型。

其实说真的,使用 Any 和 AnyObject 并不是什么令人愉悦的事情,正如开头所说,这都是为妥协而存在的。如果在我们自己的代码里需要大量经常地使用这两者的话,往往意味着代码可能在结构和设计上存在问题,应该及时重新审视。简单来说,我们最好避免依赖和使用这两者,而去尝试明确地指出确定的类型。

2017-03-17 13:40:08 frankisbaby 阅读数 2165

swift为不确定类型提供了两种特殊的类型别名:
这里写图片描述
下边创建了可以存储类型的数组:
这里写图片描述
things 数组包含两个 Int 值,两个 Double 值,一个 String 值,一个元组 (Double, Double),一个Movie实例“Ghostbusters”,以及一个接受 String 值并返回另一个 String 值的闭包表达式。
可以使用switch语句进行遍历并且进行相应的操作:
这里写图片描述
其中:
case let someInt as Int:
print(“an integer value of (someInt)”)
相当于
case let soneInt = thing as Int:{
print(“an integer value of (someInt)”)
}
这里写图片描述
数组中添加可选类型会报警告,转换为Any类型可以去掉警告。因为可选类型包括可选类型。