any data swift
2016-04-20 14:40:00 weixin_34080951 阅读数 20

Any and AnyObject

1780490-90fd1b77bb1478ab.png
Any and AnyObject
2015-06-16 22:58:44 crazyeveryday 阅读数 373

class ca{

    

}

class cb:ca{

    

}

var library:[Any] = [

ca(),

cb(),

1,

]


for item in library{

    if let intitem = item as? Int{

    println(item);

    }

}

println("-------分界线-------");

var items:[AnyObject]=[

ca(),

cb(),]

for item in items as! [ca]{

    println(item);

}

2016-07-04 16:05:37 u010309384 阅读数 294
Any : class、struct、enum

AnyObject: class ,因为所有的类都实现了AnyObject的协议方法,Object-C中的id = AnyObject? 
2017-12-23 16:11:10 weixin_33985507 阅读数 8

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()方法创建对象

2018-04-25 03:14:10 weixin_34289454 阅读数 12

这是一片译文。原文链接在这儿~

Swift3以一种比以前的版本更强大的方式结合Objective-C的API。对于实例变量,Swift2把Objective-C中的id类型映射到 Swift中的AnyObject类型,通常它只能持有class类型。Swift2也为一些桥接值类型提供了隐式转换到AnyObject类型,例如:String, Array, Dictionary, Set 和一些数字,作为一种便利让Swift本地类型能够轻松的用于那些需要NSStringNSArray或者其他来自于Foundation的容器类的Cocoa API。这些转换和Swift语言的剩余部分是不一致的,这让理解到底什么能被用作AnyObject变的困难,导致出错。

在Swift3里,id类型被映射成Any类型,它描述了一个任何类型的值,无论是类,枚举,结构体,还是任何其他Swift类型。这个改变让Objective-C里API在Swift中更灵活,因为Swift定义的值类型可以被传递给Objective-C的API,并且作为Swift类型被取出来,消除了手动封包的需要。这些好处也扩展到了集合:Objective-C集合类型NSArray, NSDictionary, 和 NSSet,之前只接受AnyObject类型的元素,现在可以持有Any类型的元素。对于散列容器,比如DictionarySet,有一个新类型AnyHashable,可以持有一个任何遵守Swift 中Hashable协议的类型的值。总的来说,从Swift2到Swift3发生了下面这些类型映射改变:

Objective-CSwift 2Swift 3
idAnyObjectAny
NSArray *[AnyObject][Any]
NSDictionary *[NSObject: AnyObject][AnyHashable: Any]
NSSet *Set<NSObject>Set<AnyHashable>

许多情况下,为了响应这个改变,你的代码不需要明显地改变。Swift2依赖值类型隐式转换成AnyObject的代码在Swift3里仍然好使,只需要作为Any来传递。然而,有些地方你不得不改变变量和方法的声明类型,从而获得最好的Swift3编码体验。并且如果你的代码显式地使用AnyObject或者Cocoa类,例如NSString, NSArray, 或者 NSDictionary,你将会需要显式地使用as NSString 或者as String引入更多的角色,因为在Swift3里,对象类型和值类型的隐式转换不再被允许。

重写方法和遵守协议

当继承一个Objective-C类并且重写它的方法,或者遵守一个Objective-C协议,当父类方法使用了id时,这些方法的类型签名需要被更新。一些普通的例子比如:NSObjectisEqual:方法,NSCopying协议的copyWithZone:方法。Swift2里,你会写一个像这样的继承NSObject并遵守NSCopying协议的子类:

// Swift 2
class Foo: NSObject, NSCopying {
	override func isEqual(_ x: AnyObject?) -> Bool { ... }
	func copyWithZone(_ zone: NSZone?) -> AnyObject { ... }
}
复制代码

Swift3里,除了把方法名从copyWithZone(_:)改为copy(with:),你还需要使用Any代替AnyObject改变这些方法的签名:

// Swift 3
class Foo: NSObject, NSCopying {
	override func isEqual(_ x: Any?) -> Bool { ... }
	func copy(with zone: NSZone?) -> Any { ... }
}
复制代码

无类型集合

属性列表,JSON和用户信息字典在Cocoa里很常见,Cocoa原生把这些看做无类型的集合。出于这个目的,在Swift2里,用AnyObject 或者 NSObject元素构建Array, Dictionary, 或者 Set很必要,依靠隐式桥接转换来处理值类型:

// Swift 2
struct State {
	var name: String
	var abbreviation: String
	var population: Int
	var asPropertyList: [NSObject: AnyObject] {
		var result: [NSObject: AnyObject] = [:]
		// Implicit conversions turn String into NSString here…
		result["name"] = self.name
		result["abbreviation"] = self.abbreviation
		// …and Int into NSNumber here.
		result["population"] = self.population
		return result
	}
}
let california = State(name: "California",
                       abbreviation: "CA",  
                       population: 39_000_000)
NSNotification(name: "foo", object: nil, userInfo: california.asPropertyList)
复制代码

或者,你可以使用Cocoa的容器类,例如:NSDictionary:

// Swift 2
struct State {
	var name: String
	var abbreviation: String
	var population: Int
	var asPropertyList: NSDictionary {
		var result = NSMutableDictionary()
		// Implicit conversions turn String into NSString here…
		result["name"] = self.name
		result["abbreviation"] = self.abbreviation
		// …and Int into NSNumber here.
		result["population"] = self.population
		return result.copy()
	}
}
let california = State(name: "California",  abbreviation: "CA", population: 39_000_000)
// NSDictionary then implicitly converts to [NSObject: AnyObject] here.
NSNotification(name: "foo", object: nil, userInfo: california.asPropertyList)
复制代码

Swift3里面,隐式转换不存在了,因此以上的代码片段都不能正常工作。迁移器可能建议给每个转换单独添加as转换来让它正常运行,但是有更好的解决方案。现在Swift把Cocoa API作为Any和/或AnyHashable类型的可接受集合引入,因此我们可以用[AnyHashable: Any]修改集合类型,而不是[NSObject: AnyObject]或者NSDictionary,而不需要改变其他的代码:

// Swift 3
struct State {
	var name: String
	var abbreviation: String
	var population: Int
	// Change the dictionary type to [AnyHashable: Any] here...
	var asPropertyList: [AnyHashable: Any] {
		var result: [AnyHashable: Any] = [:]
		// No implicit conversions necessary, since String and Int are subtypes
		// of Any and AnyHashable
		result["name"] = self.name
		result["abbreviation"] = self.abbreviation
		result["population"] = self.population
		return result
	}
}
let california = State(name: "California", abbreviation: "CA", population: 39_000_000)
// ...and you can still use it with Cocoa API here
Notification(name: "foo", object: nil, userInfo: california.asPropertyList)
复制代码

AnyHashable类型

Swift的Any类型能够持有任何类型,但是DictionarySet要求键是Hashable的,所以Any太宽泛了。从Swift3开始,Swift标准库提供了一个新类型AnyHashable。和Any一样,它作为所有Hashable类型的父类型,因此StringInt和其他可散列类型的值可以被隐式的作为AnyHashable的值,并且一个AnyHashable内部的类型可以用is, as!, or as?这些动态类型装换操作符动态地检查。AnyHashable被用于需要从Object-C中引入无类型的NSDictionary 或者 NSSet对象,但是在纯Swift里创建复杂的集合和字典也有用。

针对未桥接的上下文进行显示转换

在特定的受限制的情况下,Swift不能自动桥接C和Objective-C结构。例如,一些C和Cocoa的API使用id *指针作为输入和输出参数,并且由于Swift不能够静态的决定这个指针怎么使用,它就不能在内存里自动对这个值上执行桥接转换。像这样的情况下,这个指针将仍然是UnsafePointer<AnyObject>。如果你需要使用这些未桥接的API之一,你可以使用显式桥接转换,在你的在代码里明确地写上as Type 或者 as AnyObject

// ObjC
@interface Foo
- (void)updateString:(NSString **)string;
- (void)updateObject:(id *)obj;
@end
复制代码

// Swift
func interactWith(foo: Foo) -> (String, Any) {
	var string = "string" as NSString // explicit conversion
	foo.updateString(&string) // parameter imports as UnsafeMutablePointer<NSString>
	let finishedString = string as String
	var object = "string" as AnyObject
	foo.updateObject(&object) // parameter imports as UnsafeMutablePointer<AnyObject>
	let finishedObject = object as Any
	return (finishedString, finishedObject)
}
复制代码

另外,Objective-C中的协议在Swift中依然是受类限制的,因此你不能让Swift结构体和枚举直接遵守Objective-C协议或者用轻便的泛型类使用它们。你需要用它们的协议和API明确地转换String as NSString, Array as NSArray等等。

AnyObject成员检查

Any没有像AnyObject那样的魔术方法查找行为。这可能会打断那些查找一个属性或者发送一个消息给一个无类型的Object-C对象的Swift2代码。例如,这段Swift2代码:

// Swift 2
func foo(x: NSArray) {
	// Invokes -description by magic AnyObject lookup
	print(x[0].description)
}
复制代码

在Swift3里将会抱怨description不是Any的一个成员。你可以把这个值用x[0] as AnyObject转换,从而重新获得动态特性:

// Swift 3
func foo(x: NSArray) {
	// Result of subscript is now Any, needs to be coerced to get method lookup
	print((x[0] as AnyObject).description)
}
复制代码

或者,把这个值强制转换为你期望的那个实体对象:

func foo(x: NSArray) {
	// Cast to the concrete object type you expect
	print((x[0] as! NSObject).description)
}
复制代码

Object-C中的Swift值类型

Any能够持有任何结构体,枚举,元组,或者是你能够在这个语言里定义的其他类型。Swift3里的Object-C桥接可以反过来把任何Swift值呈现为id-Object-C兼容对象。这使得在Cocoa容器、userInfo字典和其他对象里储存自定义的Swift值类型更加容易。例如,在Swift2里,你需要把你的数据类型改成类,或者手动封包它们,来把它们的值附加给一个NSNotification

// Swift 2
struct CreditCard { number: UInt64, expiration: NSDate }
let PaymentMade = "PaymentMade"
// We can't attach CreditCard directly to the notification, since it
// isn't a class, and doesn't bridge.
// Wrap it in a Box class.
class Box<T> {
	let value: T
	init(value: T) { self.value = value }
}
let paymentNotification = NSNotification(name: PaymentMade, object: Box(value: CreditCard(number: 1234_0000_0000_0000, expiration: NSDate())))
复制代码

Swift3里,我们不需要封包,可以直接把这个对象附加给通知:

// Swift 3
let PaymentMade = Notification.Name("PaymentMade")
// We can associate the CreditCard value directly with the Notification
let paymentNotification =
	Notification(name: PaymentMade, object: CreditCard(number: 1234_0000_0000_0000, expiration: Date()))
复制代码

在Object-C里,这个CreditCard值将会是id兼容的,NSObject--实现了isEqual:, hash, 和 description的遵守对象,使用Swift的Equatable, Hashable, 和 CustomStringConvertible实现,如果它们存在原始的Swift类型。Swift中,这个值可以通过动态转换回它原始的类型而被取回:

// Swift 3
let paymentCard = paymentNotification.object as! CreditCard
print(paymentCard.number) // 1234000000000000
复制代码

在Swift3.0中,你要清楚一些常见的Swift和Object-C结构类型会桥接为不透明对象,而不是符合语言习惯的Cocoa对象。例如,虽然Int, UInt, Double, 和 Bool桥接为NSNumber,而其他有大小的数字类型例如Int8, UInt16等只桥接为不透明的对象。Cocoa结构体例如CGRect, CGPoint, 和 CGSize也桥接为不透明对象,即使大部分用到它们的Cocoa API期望它们封包为NSValue实例。如果你看到unrecognized selector sent to _SwiftValue这样的错误,这表明 Objective-C代码试图在一个不透明的Swift值类型上引入一个方法,你可能需要用一个Objective-C代码期望的类的实例手动封包那个值。

一个需要特别注意的问题是可选值。Any能够持有任何东西,包括一个可选值,因此把一个包装的可选值传给一个Objective-C API而不先检查它是可能的,即使这个API声明为需要nonnull id。这通常会表现为一个包含_SwiftValue的运行时错误,而不是编译期错误。Xcode8.1beta版里的Swift3.0.1通过定位上述的NSNumber, NSValue, 和 Optional桥接限制实现这些提议,来显式地处理数字类型,Objective-C结构体和可选值。

为了避免传递兼容问题,你不应该依赖_SwiftValue类的不透明对象的实现细节,因为将来的Swift版本可能允许更多的Swift类型桥接到符合语言习惯的Object-C类型。


Swift——Any和 AnyObject区别

阅读数 398

AnyObject可以代表任何class类型的实例Any可以表示任意类型,甚至包括方法(func)类型一、AnyObject。写过Objective-C的朋友会知道在Objective-C中有一个叫做id的类型。编译器不会对向声明的为id的变量进行类型检查,它可以表示任意类的实例。在Cocoa框架中不很多地方都使用了id来进行像参数传递和方法返回这样的工作,这是Objective

博文 来自: u012189584

Swift:AnyObject,Any和AnyClass

阅读数 7

Swift3.0和Swift2.0写法对比Any和AnyObject这两个类型都是Swift中很早就出现的类型,但是我们经常使用AnyObject,很少使用Any。AnyObject类似于OC中的id类型,表示任意的class的实例对象,但是在Swift中,例如我们常见的String和Array都变为结构体了,而且在Swift3.0中,更多的类型...

博文 来自: weixin_34013044

Swift中Any & AnyObject

阅读数 4

在学习Swift的过程中,进行json类型转换的时候,老是奇怪应该在[String:xxx]里面填什么,是Any还是AnyObject呢?上网搜了一下这两者的区别,大概搞清楚了些。根据官方文档的说法:Any代表的是所有类型的实例,包括function类型AnyObject则代表的是所有class类型的实例在Swift2的时候,OC中的id类型在swift中映射为AnyObject,而...

博文 来自: weixin_33971977

Swift Any,AnyObject,NSObject

阅读数 21

AnyAny可以表示任何类型。AnyObjectAnyObject是一个成员为空的协议,任何对象都实现了这个协议,在Swift中可以指代任何类的对象。NSObjectNSObject则是ObjectiveC语言中的基类,所有的OC类都继承自NSObject。...

博文 来自: weixin_33957648

Swift - AnyObject与Any的区别

阅读数 8

1,AnyObject:代表任何class类型的对象实例。1234567891011121314151617classMan{} classWoman{} letman=Man()letwoman=Woman()vararr:[AnyOb...

博文 来自: weixin_33716154
没有更多推荐了,返回首页