anyclass swift
2016-02-16 14:56:00 weixin_33887443 阅读数 16

在Objective-C中,每一个class 都会有一个静态类属性,比如:

[AClass class]
[BClass class]
[CClass class]。。。。
但是这个类属性在swift中并不存在,AnyClass 是获得类的类型的一个操作,在swift中,可以这么来写:
AClass.self
BClass.self。。。

参考网址:

2017-12-23 16:11:10 weixin_33985507 阅读数 13

Swift 3.0 和 Swift 2.0 写法对比

Any和AnyObject

这两个类型都是Swift中很早就出现的类型,但是我们经常使用AnyObject,很少使用Any。

AnyObject类似于OC中的id类型,表示任意的class的实例对象,但是在Swift中,例如我们常见的String和Array都变为结构体了,而且在Swift3.0中,更多的类型或者枚举被写为结构体了,AnyObject的适用范围变相被削弱了,所以在Swift3.0的API中曾经许多AnyOjbect的类型被替换为Any了。

当然,这对于我们使用这些API没有影响,但是在我们自己定义方法时,如果需要用到AnyObject,就需要认真考虑一下该用AnyObject还是Any了。

AnyObject

AnyObject是个什么玩意呢? 有什么用呢?

我们点进其头文件看一下, 发现@objc public protocol AnyObject { }, 这个单词protocol大家都认识吧, 对AnyObject是一个协议, 它的注释第一行有这么一句话:The protocol to which all classes implicitly conform.意思是所有的类都隐式遵守了这个协议.

AnyObject有什么用呢?有过Objective-C开发经验的人肯定知道id, 它可以表示任意类的实例, 编译器不会对向声明为 id 的变量进行类型检查.而 Swift为了与 Cocoa 架构进行协作开发,就将原来的id用 AnyObject 来进行替代。

AnyObject的自动类型转换

Objective-C的NSArray里面只能保存对象类型, 不能添加基本数据类型, 枚举,结构体等.但是如果我们在Swfit里面将Array的元素类型声明成AnyObject会发生什么呢? 我们定义一个数组:let array:[Any] = ["123", 123], 在其下面插入一个断点, 如下图所示

截图.png

没错, 它将基本数据类型`int`转换成了Objective-C中的`NSNumber`对象,

所以在Swift中, 我们将基本数据类型或者enum和struct通过AnyObject来保存也不会像Objective-C那样报错, 因为Swift中很多数据类型可以和Objective-C中的数据类型进行自动转换

Any

Any是什么? 同上, 我们进入Any所在的头文件:public typealias Any = protocol<>, 关于type alias, 大家可以进入喵神的TYPEALIAS 和泛型接口这篇文章进行详细了解. 我们直接看Any的注释:/// The protocol to which all types implicitly conform., (小tip:///在Swift中就是文档注释), 意思是所有的类型, 都隐式的遵守这个协议.

说得更直白一点, 就是所有的类型都可以用Any表示, 包括基本数据类型, enum, struct, func(方法)等等.

此时, 我们和AnyObject, 我们也定义一个数组, 用Any类型保存:let array: [Any] = ["123", 123], 同样插入一个断点, 如图:

截图.png

显而易见, `Any `并不会如同`AnyObject `一样进行数据类型的转换

AnyClass

AnyClass: 表示任意类的元类型.它所在的头文件这样写道:public typealias AnyClass = AnyObject.Type, 它的注释第一句就指明了:/// The protocol to which all class types implicitly conform., 任意类的类型都隐式遵守这个协议.AnyObject.Type中的.Type就是获取元类型, 辟如你有一个Student类,Student.Type就是获取Student的元类型.

如果一个变量/常量的类型是AnyClass,AnyClass并不知道其具体的类型, 所以需要将他转换为已知的类型, 然后再调用init()方法创建对象

2017-02-13 14:54:49 Calvin_CN 阅读数 504

这次写一下关于Swift中AnyClass的使用以及动态类型的实例化和使用场景

AnyClass与AnyObject

Swift中,任何自定义的对象都是AnyClass的子类,类似于Java的Object类(但注意,这和Objective-C的NSObject不同,后者在Swift中是专门的UIKit或者AppKit框架里面定义的类型,而非语言所规定的类型)

AnyClass

The protocol to which all class types implicitly conform.

typealias AnyClass = AnyObject.Type

AnyObject

The protocol to which all classes implicitly conform.

protocol AnyObject { ... }

但是注意,这个AnyObject.Type是一个毕竟是一个接口的Property,所以只能在函数的参数里面使用,如果想要直接获取某个类(而非实例)的类型,使用类名.self即可;如果想要获取一个实例的类的类型,使用.dynamicType;对了,如果对象是NSObject的实例(iOS开发中常用),用classForCoder也是一个选择

class Test {}
func f(s: AnyClass) {
    print(s)
}
let a = Test.self
let b = Test().dynamicType
let c:AnyClass = "test".classForCoder //注意此时加了classForCoder的方法调用,编译器会推导出""是一个NSString的实例而不是String
f(a) //Test
f(b) //Test
f(c) //NSString

动态实例化

既然我们有了某个AnyObject的Type,这样我们就可以直接构造出一个类型的实例。使用AnyObject都有的.init方法即可,当然,AnyObject本身并没有init的构造方法……

let d = a.init() // d is an instance of Test
let e = (c as! NSString.Type).init(stringLiteral: "test") // e is "test"

当然,你也许肯定奇怪那个required的init是什么意思,其实这是为了避免出现你使用的这个Test.Type有继承的子类,然后子类的构造函数中使用了这个Type来构造父类这种边界情况出现(考虑的真细……)

Use an initializer expression to construct an instance of a type from that type’s metatype value. For class instances, the initializer that’s called must be marked with the required keyword or the entire class marked with the final keyword.

而且对于一个Protocol,可以用.Protocol来获取这个Protocol的类型(还是AnyClass),也可以用self来统一处理,因为实际上

metatype-type(.self) -&gt; type.Type | type.Protocol

这样的话,有了动态就可以开始干活了

Swift的反射

或许你也想,既然我有了动态的类型实例,那么是不是能通过类似Java的反射,获取某个类型的所有Property,然后直接访问这个Property呢?答案也是有的,不过在Swift中很少用到,这里用到到了Mirror

Representation of the sub-structure and optional “display style” of any arbitrary subject instance.

struct Mirror { ... }

class Person {
    var whatThisProperty:String
    init(name:String) {
        self.whatThisProperty = name
    }
}
let p = Person(name: "Bob")
let mirror = Mirror(reflecting: p)
mirror.children.forEach {
    print("\($0.label!): \($0.value)")
}

这里的children返回的是一个AnyForwardCollection,也是可以像数组一般用index来访问或者forEach遍历的,不过索引顺是序按照你的Property的声明顺序

最后的小应用

由于我也不怎么会写iOS,有时候遇到这样一种情况: 我提供了一个3D Touch的按钮,四个按钮会对应四种ViewController,iOS提供的API可以获取到用户点击的那个按钮对应的设置的一个字符串值,那么,我可以这样来玩……

// 3D Touch 传入的字符串来判断返回某个ViewController
static func shortcutToViewController(type:String) -> UIViewController.Type {
    switch type {
    case "pe":
        return RunningViewController.self
    case "curriculum":
        return CurriculumViewController.self
    case "card":
        return SeuCardViewController.self
    case "nic":
        return NicViewController.self
    default: return UIViewController.self
    }
}

这是用来判断字符串来产生对应的ViewController.Type的,然后,在真正需要实例化一个新的ViewController来显示一个View的时候,再实例化

func pushToViewController(vc: UIViewController.Type) {
    // 确保要显示的ViewController不是顶层显示的ViewController
    guard let duplication = navigationController?.topViewController?.isKindOfClass(vc) else { return }
    if duplication { // 检查失败,重复的ViewController,不需要跳转
        return
    }
    let viewController = vc.init(nibName: "\(vc.classForCoder())", bundle: nil) // 初始化ViewController
    navigationController?.pushViewController(viewController, animated: true)
}

这也是一种比较奇怪的方式……不过如果不这样,就会导致在主类和上层里面引入过多的Switch Case或者导致代码中出现纯字符串定义的nibName,这对以后重构非常不利。

结束语

嗯,好久没写东西了……主要最近在学编译原理,之后会有几篇讲解通过Java实现一个简单的支持CFG的Yacc(误)的东西……顺便就当复习编译原理的Parser部分了。

Swift如今开源了: Swift ,不到几天Star就超过了2年出头的Rust(lol)……现如今Star也到了2W5的程度

虽然UIKit和AppKit这种宝贵的财富Apple肯定不会开源,不过Swift标准库的实现也是越来越完善,而且也有Linux的版本,很多第三方的库开始加入了对Linux的支持(非面向iOS和OS X开发的,比如对SQLite,Redis的wrapper)

Swift作为一个Rust的对手,一个完全抛弃了C的现代语言,之后在除客户端开发外,更可能的领域就是系统编程和服务端编程了吧。希望能够在在安全性,易用性,效率上达到一个更大的高度,让我们这种开发者也能用的爽,用的顺。

2016-03-23 13:42:00 weixin_33774615 阅读数 23

AnyObject

  • AnyObject是个什么玩意呢? 有什么用呢?

    • 我们点进其头文件看一下, 发现@objc public protocol AnyObject { }, 这个单词protocol大家都认识吧, 对AnyObject是一个协议, 它的注释第一行有这么一句话:The protocol to which all classes implicitly conform.意思是所有的类都隐式遵守了这个协议.

    • AnyObject有什么用呢?有过Objective-C开发经验的人肯定知道id, 它可以表示任意类的实例, 编译器不会对向声明为 id 的变量进行类型检查.而 Swift为了与 Cocoa 架构进行协作开发,就将原来的id用 AnyObject 来进行替代。

  • AnyObject的自动类型转换

    • Objective-C的NSArray里面只能保存对象类型, 不能添加基本数据类型, 枚举,结构体等.但是如果我们在Swfit里面将Array的元素类型声明成AnyObject会发生什么呢? 我们定义一个数组: let array:[Any] = ["123", 123], 在其下面插入一个断点, 如下图所示
1038348-5bf18403996f4b94.png
截图.png
 没错, 它将基本数据类型`int`转换成了Objective-C中的`NSNumber`对象, 

所以在Swift中, 我们将基本数据类型或者enum和struct通过AnyObject来保存也不会像Objective-C那样报错, 因为Swift中很多数据类型可以和Objective-C中的数据类型进行自动转换

Any

  • Any是什么? 同上, 我们进入Any所在的头文件: public typealias Any = protocol<>, 关于type alias, 大家可以进入喵神的<a href="http://swifter.tips/typealias/">TYPEALIAS 和泛型接口</a>这篇文章进行详细了解. 我们直接看Any的注释:/// The protocol to which all types implicitly conform., (小tip:///在Swift中就是文档注释), 意思是所有的类型, 都隐式的遵守这个协议.
  • 说得更直白一点, 就是所有的类型都可以用Any表示, 包括基本数据类型, enum, struct, func(方法)等等.
  • 此时, 我们和AnyObject, 我们也定义一个数组, 用Any类型保存: let array: [Any] = ["123", 123], 同样插入一个断点, 如图:
1038348-8400346e673f8c48.png
截图.png
 显而易见, `Any `并不会如同`AnyObject `一样进行数据类型的转换

AnyClass

  • AnyClass: 表示任意类的元类型.它所在的头文件这样写道:public typealias AnyClass = AnyObject.Type, 它的注释第一句就指明了:/// The protocol to which all class types implicitly conform., 任意类的类型都隐式遵守这个协议. AnyObject.Type中的.Type就是获取元类型, 辟如你有一个Student类, Student.Type就是获取Student的元类型.

  • 如果一个变量/常量的类型是AnyClass, AnyClass并不知道其具体的类型, 所以需要将他转换为已知的类型, 然后再调用init()方法创建对象

  • 关于AnyClass可以参考我的另一篇文章<a href="http://www.jianshu.com/p/f2503afff164">Swift:获取命名空间(namespace),动态加载类</a>

联系我

<a href="https://github.com/SunLiner">github</a>

<a href="http://www.weibo.com/5589163526/profile?rightmod=1&wvr=6&mod=personinfo&is_all=1">微博</a>

<a href="http://www.jianshu.com/users/9723687edfb5/latest_articles">简书</a>

2017-04-12 10:24:00 weixin_34013044 阅读数 13

Swift 3.0 和 Swift 2.0 写法对比

Any和AnyObject

这两个类型都是Swift中很早就出现的类型,但是我们经常使用AnyObject,很少使用Any。

AnyObject类似于OC中的id类型,表示任意的class的实例对象,但是在Swift中,例如我们常见的String和Array都变为结构体了,而且在Swift3.0中,更多的类型或者枚举被写为结构体了,AnyObject的适用范围变相被削弱了,所以在Swift3.0的API中曾经许多AnyOjbect的类型被替换为Any了。

当然,这对于我们使用这些API没有影响,但是在我们自己定义方法时,如果需要用到AnyObject,就需要认真考虑一下该用AnyObject还是Any了。

AnyObject

AnyObject是个什么玩意呢? 有什么用呢?

我们点进其头文件看一下, 发现@objc public protocol AnyObject { }, 这个单词protocol大家都认识吧, 对AnyObject是一个协议, 它的注释第一行有这么一句话:The protocol to which all classes implicitly conform.意思是所有的类都隐式遵守了这个协议.

AnyObject有什么用呢?有过Objective-C开发经验的人肯定知道id, 它可以表示任意类的实例, 编译器不会对向声明为 id 的变量进行类型检查.而 Swift为了与 Cocoa 架构进行协作开发,就将原来的id用 AnyObject 来进行替代。

AnyObject的自动类型转换

Objective-C的NSArray里面只能保存对象类型, 不能添加基本数据类型, 枚举,结构体等.但是如果我们在Swfit里面将Array的元素类型声明成AnyObject会发生什么呢? 我们定义一个数组:let array:[Any] = ["123", 123], 在其下面插入一个断点, 如下图所示

截图.png

没错, 它将基本数据类型`int`转换成了Objective-C中的`NSNumber`对象,

所以在Swift中, 我们将基本数据类型或者enum和struct通过AnyObject来保存也不会像Objective-C那样报错, 因为Swift中很多数据类型可以和Objective-C中的数据类型进行自动转换

Any

Any是什么? 同上, 我们进入Any所在的头文件:public typealias Any = protocol<>, 关于type alias, 大家可以进入喵神的TYPEALIAS 和泛型接口这篇文章进行详细了解. 我们直接看Any的注释:/// The protocol to which all types implicitly conform., (小tip:///在Swift中就是文档注释), 意思是所有的类型, 都隐式的遵守这个协议.

说得更直白一点, 就是所有的类型都可以用Any表示, 包括基本数据类型, enum, struct, func(方法)等等.

此时, 我们和AnyObject, 我们也定义一个数组, 用Any类型保存:let array: [Any] = ["123", 123], 同样插入一个断点, 如图:

截图.png

显而易见, `Any `并不会如同`AnyObject `一样进行数据类型的转换

AnyClass

AnyClass: 表示任意类的元类型.它所在的头文件这样写道:public typealias AnyClass = AnyObject.Type, 它的注释第一句就指明了:/// The protocol to which all class types implicitly conform., 任意类的类型都隐式遵守这个协议.AnyObject.Type中的.Type就是获取元类型, 辟如你有一个Student类,Student.Type就是获取Student的元类型.

如果一个变量/常量的类型是AnyClass,AnyClass并不知道其具体的类型, 所以需要将他转换为已知的类型, 然后再调用init()方法创建对象

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