AnyObject และ Any ใน Swift


92

ฉันไม่เข้าใจว่าเมื่อใดควรใช้ AnyObject และเมื่อใดควรใช้ Any ใน Swift

ในกรณีของฉันฉันมีพจนานุกรม

[สตริง: ???]

??? : สามารถเป็น Int, Double, Float, String, Array, Dictionary

ใครช่วยอธิบายความแตกต่างระหว่าง Any และ AnyObject กับสิ่งที่ควรใช้ในกรณีของฉัน

Alak

คำตอบ:


117

AnyObjectใช้สำหรับประเภทการอ้างอิงเท่านั้น (คลาส) Anyสำหรับทั้งค่าและประเภทการอ้างอิง

[String: Any]ดังนั้นคุณควรไปสำหรับ

ประเภทการหล่อสำหรับ Any และ AnyObject

Swift มีสองประเภทพิเศษสำหรับการทำงานกับประเภทที่ไม่เฉพาะเจาะจง:

  • Any สามารถแสดงถึงอินสแตนซ์ประเภทใดก็ได้รวมถึงประเภทฟังก์ชัน
  • AnyObject สามารถแสดงอินสแตนซ์ของคลาสประเภทใดก็ได้

บันทึก:

ใช้AnyและAnyObjectเมื่อคุณต้องการพฤติกรรมและความสามารถที่ชัดเจนเท่านั้น จะเป็นการดีกว่าเสมอที่จะระบุประเภทที่คุณคาดหวังว่าจะใช้ได้กับโค้ดของคุณ

จากภาษาโปรแกรม Swift : https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html#//apple_ref/doc/uid/TP40014097-CH22-ID342

-

โปรดทราบว่าเมื่อคุณทำงานกับ Cocoa API เป็นเรื่องปกติที่จะได้รับ Array ของ AnyObject เนื่องจากอาร์เรย์ Objective-C ไม่ได้ถูกตรึงตรา ดังนั้นคุณต้องส่งไปยังประเภทอาร์เรย์ที่คุณต้องการ

-

แก้ไข: (22 ธันวาคม 2558)
ในคำสั่งสุดท้ายโปรดทราบว่าสิ่งนี้กำลังเปลี่ยนแปลงไปกับ Swift 2.0 และ Xcode 7
Apple ได้เปิดตัว'Lightweight' genericsใน Objective-C ดังนั้น Cocoa API จำนวนมากจึงส่งคืนประเภทที่ถูกต้องแล้ว

แก้ไข: (18 ตุลาคม 2016)
โปรดทราบว่าเป็นของสวิฟท์ 3.0 วัตถุประสงค์ -C ids จะถูกนำเข้าในขณะนี้ไม่ได้อีกต่อไปAnyAnyObject


18
โปรดทราบว่าString, ArrayและDictionaryไม่ได้เรียนสำหรับการใช้งานเหล่านี้ใด ๆ
zaph

6
ไม่ใช่ Int, Double และ Float คือ
Teejay

12
ใช่ แต่มักจะเห็นได้ชัด ยังไม่ชัดเจนNSStringนักNSArrayและNSDictionaryเป็นคลาส แต่เวอร์ชัน Swift ที่ใช้งานได้ใกล้เคียงกันนั้นไม่ใช่คลาสและเดินทางไปยังผู้พัฒนาจำนวนมาก
zaph

1
Any แสดงถึงตัวเลือกด้วยหรือไม่? หรือว่าควรจะแสดงเป็น Any?

1
@robdashnash Any ไม่ได้แสดงถึงตัวเลือก เหรอ? ควรเพิ่มเพื่อให้เป็นทางเลือก
crypt

47

ไม่ว่าคุณจะใช้AnyหรือAnyObjectขึ้นอยู่กับวัตถุประสงค์การใช้งานของคุณ:

ถ้าพจนานุกรมของคุณจะถูกใช้เพียงภายในรหัส Swift, แล้วคุณควรใช้Anyเพราะชนิดของคุณ ( Int, Double, Float, String, ArrayและDictionary) ไม่ได้เป็นวัตถุ

ถ้าคุณจะผ่านพจนานุกรมของคุณเพื่อการปฏิบัติ Objective-C ที่คาดหวังแล้วคุณควรใช้NSDictionaryAnyObject

เมื่อคุณimport Foundationหรือimport UIKitหรือimport Cocoaมันเป็นไปได้ที่จะประกาศอาร์เรย์ของคุณเป็น[String: AnyObject]แต่ในกรณีนี้สวิฟท์มีการรักษาของคุณInt, Double, Floatตัวอักษรเป็นNSNumberของคุณStringในฐานะNSStringของคุณArrayในฐานะNSArrayและพจนานุกรมของคุณเป็นNSDictionaryทั้งหมดที่เป็นวัตถุ พจนานุกรมที่ใช้AnyObjectเป็นประเภทค่าสามารถแปลงเป็นได้NSDictionaryแต่ใช้Anyไม่ได้


1

ตามเอกสาร Swift ของ Apple ระบุว่า

  • ใด ๆ ก็สามารถแสดงถึงอินสแตนซ์ประเภทใดก็ได้รวมถึงประเภทฟังก์ชันและประเภททางเลือก
  • AnyObject สามารถแสดงอินสแตนซ์ของคลาสประเภทใดก็ได้

สำหรับรายละเอียดเพิ่มเติมโปรดตรวจสอบสิ่งนี้: บล็อก


1

ตรวจสอบคำตอบ SO นี้ :

Generics เป็นประเภทที่ปลอดภัยหมายความว่าหากคุณส่งสตริงเป็นแบบทั่วไปและพยายามใช้เป็นจำนวนเต็มคอมไพเลอร์จะบ่นและคุณจะไม่สามารถคอมไพล์ของคุณได้ (ซึ่งเป็นสิ่งที่ดี) (สิ่งนี้เกิดขึ้นเนื่องจาก Swift ใช้การพิมพ์แบบคงที่และสามารถให้ข้อผิดพลาดของคอมไพเลอร์แก่คุณได้) หากคุณใช้ AnyObject คอมไพเลอร์ไม่มีความคิดว่าวัตถุนี้สามารถถือเป็น String หรือเป็นจำนวนเต็มได้หรือไม่และโดยพื้นฐานแล้วจะอนุญาตให้คุณทำอะไรก็ได้ที่คุณต้องการ (ซึ่งไม่ดี) ราวกับว่าคุณพยายามใช้วัตถุที่ได้รับ ส่งผ่านเป็นสตริงเมื่อเป็นจำนวนเต็มแอปพลิเคชันจะหยุดทำงาน (สิ่งนี้เกิดขึ้นเนื่องจาก Swift ใช้การพิมพ์แบบไดนามิกและจะทำให้คุณมีข้อผิดพลาดรันไทม์เท่านั้น)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.