@import vs #import - iOS 7


432

Tôi đang chơi xung quanh với một số tính năng mới của iOS 7 và làm việc với một số Hiệu ứng hình ảnh như được thảo luận trong video WWDC "Triển khai giao diện người dùng tham gia trên iOS". Để tạo hiệu ứng mờ trong mã nguồn cho phiên, UIImageđã được mở rộng thông qua danh mục nhập UIKit như sau:

@import UIKit;

Tôi nghĩ rằng tôi đã thấy một cái gì đó về điều này trong một video phiên khác nhưng tôi gặp khó khăn khi tìm thấy nó. Tôi đang tìm kiếm bất kỳ thông tin cơ bản về thời điểm sử dụng này. Nó chỉ có thể được sử dụng với các khung của Apple? Những lợi ích của việc sử dụng chỉ thị trình biên dịch này có đủ để tôi quay lại và cập nhật mã cũ không?


Câu trả lời:


838

Đây là một tính năng mới gọi là Mô-đun hoặc "nhập ngữ nghĩa". Có nhiều thông tin hơn trong các video WWDC 2013 cho Phiên 205404 . Đó là một cách thực hiện tốt hơn các tiêu đề được biên dịch trước. Bạn có thể sử dụng các mô-đun với bất kỳ khung hệ thống nào trong iOS 7 và Mavericks. Các mô-đun là một bao bì cùng với khung thực thi và các tiêu đề của nó và được quảng cáo là an toàn và hiệu quả hơn #import.

Một trong những lợi thế lớn của việc sử dụng @importbạn không cần thêm khung trong cài đặt dự án, nó được thực hiện tự động . Điều đó có nghĩa là bạn có thể bỏ qua bước mà bạn nhấp vào nút dấu cộng và tìm kiếm khung (hộp công cụ vàng), sau đó di chuyển nó đến nhóm "Khung". Nó sẽ lưu nhiều nhà phát triển khỏi các thông báo "Lỗi liên kết" khó hiểu.

Bạn thực sự không cần phải sử dụng @importtừ khóa. Nếu bạn chọn sử dụng các mô-đun, tất cả #importvà các #includechỉ thị sẽ được ánh xạ để sử dụng @importtự động. Điều đó có nghĩa là bạn không phải thay đổi mã nguồn của mình (hoặc mã nguồn của các thư viện mà bạn tải xuống từ nơi khác). Giả sử sử dụng các mô-đun cũng cải thiện hiệu suất xây dựng, đặc biệt là nếu bạn chưa sử dụng PCH tốt hoặc nếu dự án của bạn có nhiều tệp nguồn nhỏ.

Các mô-đun được xây dựng trước cho hầu hết các khung của Apple (UIKit, MapKit, GameKit, v.v.). Bạn có thể sử dụng chúng với các khung do bạn tự tạo: chúng được tạo tự động nếu bạn tạo khung Swift trong Xcode và bạn có thể tự tạo tệp ".modulemap" cho bất kỳ thư viện Apple hoặc bên thứ ba nào .

Bạn có thể sử dụng hoàn thành mã để xem danh sách các khung có sẵn:

nhập mô tả hình ảnh ở đây

Các mô-đun được bật theo mặc định trong các dự án mới trong Xcode 5 . Để bật chúng trong dự án cũ hơn, hãy vào cài đặt xây dựng dự án của bạn, tìm kiếm "Mô-đun" và đặt "Bật mô-đun" thành "CÓ". "Khung liên kết" cũng phải là "CÓ":

Bạn phải sử dụng Xcode 5 và SDK iOS 7 hoặc Mavericks, nhưng bạn vẫn có thể phát hành cho các hệ điều hành cũ hơn (giả sử iOS 4.3 hoặc bất cứ điều gì). Các mô-đun không thay đổi cách mã của bạn được xây dựng hoặc bất kỳ mã nguồn nào.


Từ các slide WWDC:

  • Nhập khẩu mô tả ngữ nghĩa đầy đủ của một khung
  • Không cần phân tích các tiêu đề
  • Cách tốt hơn để nhập giao diện của khung
  • Tải biểu diễn nhị phân
  • Linh hoạt hơn các tiêu đề được biên dịch trước
  • Miễn dịch với các hiệu ứng của định nghĩa vĩ mô địa phương (ví dụ #define readonly 0x01)
  • Được bật cho các dự án mới theo mặc định

Để sử dụng rõ ràng các mô-đun:

Thay thế #import <Cocoa/Cocoa.h>bằng@import Cocoa;

Bạn cũng có thể nhập chỉ một tiêu đề với ký hiệu này:

@import iAd.ADBannerView;

Các mô hình con tự động hoàn thành cho bạn trong Xcode.


15
@DaveDeLong & Klaas: Cảm ơn! Tôi phải thừa nhận rằng tôi không biết gì về các mô-đun khi lần đầu tiên tôi trả lời điều này. Tôi đã đi và xem Phiên 404 để tìm hiểu nó. Bài thuyết trình mà Doug Gregor (anh chàng LLVM) đã thực hiện rất tốt. Ngoài ra còn có một cuộc trò chuyện Mô-đun C ++ giải thích những lợi thế ở đây: youtube.com/watch?v=4Xo9iH5VLQ0
vua nevan

3
@ nevan-- cảm ơn vì câu trả lời. Tôi chỉ muốn thêm rằng các mô-đun hiện không hỗ trợ bên thứ 3 và các khung riêng của bạn.
jamdaddy25

Bạn có thể sử dụng điều này cho các lớp học của riêng bạn?
cfischer

5
Tôi nghĩ bạn sẽ có thể @import khung của bên thứ 3 nếu được cung cấp một module.map thích hợp. Tài liệu mô-đun LLVM clang
bames53

1
Ồ, thực sự có vẻ như nó @import sqlite3hoạt động với tôi vì tôi đã tạo ra module.map của riêng mình cho nó và khi tôi nhận ra sqlite được đưa vào OS X và gỡ bỏ module.map của tôi, trình biên dịch tiếp tục sử dụng mô-đun cũ.
bames53

46

Câu trả lời hay mà bạn có thể tìm thấy trong cuốn sách Học ca cao với Objective-C (ISBN: 980-1-491-90139-7)

Các mô-đun là một phương tiện mới bao gồm và liên kết các tệp và thư viện vào các dự án của bạn. Để hiểu cách các mô-đun hoạt động và những lợi ích mà chúng có, điều quan trọng là phải nhìn lại lịch sử của Objective-C và câu lệnh #import Bất cứ khi nào bạn muốn bao gồm một tệp để sử dụng, bạn thường sẽ có một số mã giống như sau:

#import "someFile.h"

Hoặc trong trường hợp khung:

#import <SomeLibrary/SomeFile.h>

Vì Objective-C là siêu ngôn ngữ của lập trình C, trạng thái #import là một sàng lọc nhỏ đối với #includetuyên bố của C. Câu lệnh #include rất đơn giản; nó sao chép mọi thứ nó tìm thấy trong tệp được bao gồm vào mã của bạn trong quá trình biên dịch. Điều này đôi khi có thể gây ra vấn đề đáng kể. Ví dụ, hãy tưởng tượng bạn có hai tệp tiêu đề: SomeFileA.hSomeFileB.h; SomeFileA.hbao gồm SomeFileB.h, và SomeFileB.hbao gồm SomeFileA.h. Điều này tạo ra một vòng lặp và có thể gây nhầm lẫn cho coimpiler. Để đối phó với điều này, các lập trình viên C phải viết các vệ sĩ chống lại loại sự kiện này xảy ra.

Khi sử dụng #import, bạn không cần phải lo lắng về vấn đề này hoặc viết các bộ bảo vệ tiêu đề để tránh nó. Tuy nhiên, #importvẫn chỉ là một hành động sao chép và dán được tôn vinh, gây ra thời gian biên dịch chậm giữa một loạt các vấn đề nhỏ hơn nhưng vẫn rất nguy hiểm (chẳng hạn như một tệp được ghi đè lên một cái gì đó bạn đã khai báo ở nơi khác trong mã của riêng bạn.)

Các mô-đun là một nỗ lực để có được xung quanh này. Chúng không còn là một bản sao và dán vào mã nguồn, mà là một đại diện nối tiếp của các tệp được bao gồm có thể được nhập vào mã nguồn của bạn chỉ khi và khi cần thiết. Bằng cách sử dụng các mô-đun, mã thường sẽ biên dịch nhanh hơn và an toàn hơn so với sử dụng #include hoặc #import.

Quay trở lại ví dụ trước về nhập khung:

#import <SomeLibrary/SomeFile.h>

Để nhập thư viện này dưới dạng mô-đun, mã sẽ được thay đổi thành:

@import SomeLibrary;

Điều này có thêm phần thưởng Xcode liên kết khung công tác Một số thư viện vào dự án. Các mô-đun cũng cho phép bạn chỉ bao gồm các thành phần bạn thực sự cần vào dự án của bạn. Ví dụ: nếu bạn muốn sử dụng thành phần AwesomeObject trong khung AwesomeL Library, thông thường bạn sẽ phải nhập mọi thứ chỉ để sử dụng một phần. Tuy nhiên, bằng cách sử dụng các mô-đun, bạn chỉ có thể nhập đối tượng cụ thể mà bạn muốn sử dụng:

@import AwesomeLibrary.AwesomeObject;

Đối với tất cả các dự án mới được thực hiện trong Xcode 5, các mô-đun được bật theo mặc định. Nếu bạn muốn sử dụng các mô-đun trong các dự án cũ (và bạn thực sự nên), chúng sẽ phải được bật trong cài đặt xây dựng của dự án. Khi bạn làm điều đó, bạn có thể sử dụng cả hai #importvà các @importcâu lệnh trong mã của mình cùng nhau mà không cần quan tâm.


Không có tùy chọn nào trong dự án của tôi (Xcode 6) mà lần đầu tiên tôi bắt đầu trên Xcode 4 để kích hoạt các mô-đun. Tôi có thể thêm nó bằng tay bằng cách nào đó?
Tuyệt vời-o

Mục tiêu xây dựng là iOS 6, tôi nghĩ đây là vấn đề
Awesome-o

4

Nó hiện chỉ hoạt động cho các khung hệ thống được xây dựng. Nếu bạn sử dụng #importnhư apple vẫn thực hiện nhập UIKitkhung trong đại biểu ứng dụng thì nó sẽ được thay thế (nếu mô-đun được bật và được công nhận là khung hệ thống) và trình biên dịch sẽ ánh xạ lại thành mô-đun nhập và không phải nhập tệp tiêu đề . Vì vậy, việc rời khỏi #importsẽ giống như được chuyển đổi thành nhập mô-đun nếu có thể



1

Có một vài lợi ích của việc sử dụng các mô-đun. Bạn chỉ có thể sử dụng nó với khung của Apple trừ khi bản đồ mô-đun được tạo. @importtương tự như các tệp tiêu đề biên dịch trước khi thêm vào .pchtệp, đây là một cách để điều chỉnh ứng dụng trong quá trình biên dịch. Ngoài ra, bạn không phải thêm thư viện theo cách cũ, @importthực tế sử dụng nhanh hơn và hiệu quả hơn nhiều. Nếu bạn vẫn tìm kiếm một tài liệu tham khảo tốt, tôi sẽ khuyên bạn nên đọc bài viết này .


0

Lịch sử:

#include => #import => .pch => @import

#include vs #import
.pch - Tiêu đề được biên dịch sẵn

Mô-đun - @import

Product Name == Product Module Name 

@modulekhai báo nói với trình biên dịch để tải một nhị phân được biên dịch sẵn của khung làm giảm thời gian xây dựng . Modular Framework chứa .modulemap[Giới thiệu]

Nếu tính năng mô-đun được bật trong dự án Xcode #include#importcác lệnh được tự động chuyển đổi thành @importmang lại tất cả lợi thế

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.