游乐场和项目之间的差异

游乐场和项目之间的差异

本文介绍了游乐场和项目之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在回答另一个问题的过程中,我在 Playground 中遇到了一个奇怪的错误.我有以下代码来测试对象是 ArrayDictionary 还是 Set:

In the course of answering another question, I came across a weird bug in Playground. I have the following code to test if an object is an Array, Dictionary or a Set:

import Foundation

func isCollectionType(value : AnyObject) -> Bool {
    let object = value as! NSObject

    return object.isKindOfClass(NSArray)
        || object.isKindOfClass(NSDictionary)
        || object.isKindOfClass(NSSet)
}

var arrayOfInt = [1, 2, 3]
var dictionary = ["name": "john", "age": "30"]
var anInt      = 42
var aString    = "Hello world"

println(isCollectionType(arrayOfInt)) // true
println(isCollectionType(dictionary)) // true
println(isCollectionType(anInt))      // false
println(isCollectionType(aString))    // false

当我将代码放入 Swift 项目或从命令行运行它时,代码按预期工作.但是 Playground 不会编译并在向下转换到 NSObject 时给我以下错误:

The code worked as expected when I put it into a Swift project or running it from the command line. However Playground wouldn't compile and give me the following error on the downcast to NSObject:

Playground execution failed: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7fb1d0f77fe8).
* thread #1: tid = 0x298023, 0x00007fb1d0f77fe8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fb1d0f77fe8)
  * frame #0: 0x00007fb1d0f77fe8
    frame #1: 0x000000010ba46e12 libswiftCore.dylib`Swift._EmptyArrayStorage._withVerbatimBridgedUnsafeBuffer (Swift._EmptyArrayStorage)<A>((Swift.UnsafeBufferPointer<Swift.AnyObject>) -> A) -> Swift.Optional<A> + 50

在所有三种情况下,构建平台都是 OS X.有谁知道如何让 Playground 一起玩?

The build platform was OS X in all three cases. Does anyone know how to get Playground to play along?

Xcode 6.3.2.斯威夫特 1.2.OS X 10.10.3 优胜美地

Xcode 6.3.2. Swift 1.2. OS X 10.10.3 Yosemite

推荐答案

并不是那个 bug 的真正原因(看起来确实很奇怪)但是...您将需要使用可选链接,因为值可以是 AnyObject:

Not really the cause of that bug (it does look weird) but...You will need to use optional chaining since value can be AnyObject:

import Foundation

func isCollectionType(value : AnyObject) -> Bool {
    if let object = value as? NSObject {
        return object.isKindOfClass(NSArray)
            || object.isKindOfClass(NSDictionary)
            || object.isKindOfClass(NSSet)
        }
    return false
}

var arrayOfInt = [1, 2, 3]
var dictionary = ["name": "john", "age": "30"]
var anInt      = 42
var aString    = "Hello world"

isCollectionType(arrayOfInt)
isCollectionType(dictionary)
isCollectionType(anInt)
isCollectionType(aString)

​​

另外值得注意的是,NSArray 和 Array 是不同的东西:

Also worth noting, NSArray and Array are different things:

  • NSArray 是一个不可变的类:

  • NSArray is an immutable class:

@interface NSArray : NSObject

虽然数组是一个结构体:

whilst Array is a struct:

struct Array: MutableCollectionType, Sliceable, _DestructorSafeContainer

考虑到这一点,isCollectionType(arrayOfInt) 返回 true 可能会令人惊讶 - 但发生了转换.

With this in mind it might be surprising that isCollectionType(arrayOfInt) returns true - but there is a conversion happening.

这篇关于游乐场和项目之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 04:39