2015-09-21 16 views
10

Làm việc trên một khuôn khổ hỗn hợp. được nhập vào bên trong tệp Obj-C nhưng các lớp bên trong không hiển thị, chỉ các lớp công khai.Làm thế nào để truy cập một lớp Swift bên trong trong Objective-C trong cùng một khuôn khổ?

Các tài liệu nêu rõ về clasees nội bộ nên có sẵn giữa Swift và obj-C:

Nhập Swift vào Objective-C
Để nhập một tập các file Swift trong mục tiêu cùng một khuôn khổ như của bạn Mã mục tiêu-C, bạn không cần cần phải nhập bất kỳ thứ gì vào tiêu đề ô cho khung. Thay vào đó, hãy nhập tệp tiêu đề do Xcode tạo cho mã Swift của bạn vào bất kỳ tệp Mục tiêu-C .m nào mà bạn muốn sử dụng mã Swift của mình. Vì tiêu đề được tạo cho mục tiêu khung là một phần của giao diện công khai của khung công tác , chỉ các khai báo được đánh dấu bằng công cụ sửa đổi công khai mới xuất hiện trong tiêu đề được tạo cho mục tiêu khung. Bạn vẫn có thể sử dụng phương pháp Swift và tài sản mà được đánh dấu bằng sửa đổi nội bộ từ bên trong phần Objective-C của khuôn khổ của bạn, miễn họ được khai báo trong một lớp kế thừa từ một lớp Objective-C . Để biết thêm thông tin về các công cụ sửa đổi cấp truy cập, hãy xem Access Control trong The Swift Programming Language (Swift 2).

Mã mẫu (Tạo một dự án mới với một khuôn khổ)

// SwiftObject.swift 

public class SwiftObject: NSObject { 
    public class func doSomething() {} 
} 

internal class YetAnotherSwiftObject: NSObject { 
    internal class func doSomething() {} 
} 

// SomeObject.m file 

@implementation SomeObject 

- (void)someMethod { 
    [SwiftObject doSomething]; 
} 

- (void)someOtherMethod { 
    [YetAnotherSwiftObject doSomething]; // Use of undeclared identifier 
} 

@end 

Trả lời

16

Như đã nêu trong các tài liệu, tờ khai được đánh dấu bằng internal sửa đổi không xuất hiện trong tạo tiêu đề, do đó, trình biên dịch không biết về chúng và do đó khiếu nại. Tất nhiên, bạn có thể gửi tin nhắn bằng cách sử dụng cách tiếp cận performSelector, nhưng điều đó không thuận tiện và dễ bị lỗi. Chúng ta chỉ cần giúp trình biên dịch biết rằng các khai báo đó là có.

tiên, chúng ta cần phải sử dụng @objc biến thuộc tính cho phép bạn chỉ định tên cho biểu tượng của bạn trong Objective-C:

// SwiftObject.swift 

@objc(SWIFTYetAnotherSwiftObject) 
internal class YetAnotherSwiftObject: NSObject { 
    internal class func doSomething() {} 
} 

Và sau đó bạn chỉ cần tạo @interface khai với các phương pháp bạn muốn sử dụng trong mã của bạn - vì vậy trình biên dịch sẽ được hạnh phúc, và cũng có thể áp dụng SWIFT_CLASS vĩ mô với tên biểu tượng bạn đã chỉ định trước đó - vì vậy các mối liên kết sẽ chọn việc thực hiện thực tế:

// SomeObject.m file 

SWIFT_CLASS("SWIFTYetAnotherSwiftObject") 
@interface YetAnotherSwiftObject : NSObject 

+ (void)doSomething; 

@end 


@implementation SomeObject 

- (void)someOtherMethod { 
    [YetAnotherSwiftObject doSomething]; // Should work now !!! 
} 

@end 
  • Tôi đã sử dụng khai báo giao diện trong tệp .m chỉ để rõ ràng, tùy chọn tốt hơn là kết hợp các khai báo đó trong tệp .h và bao gồm nó.
  • Bằng cách khai báo các phương thức trong giao diện đó, chúng tôi hứa với trình biên dịch và sẽ không phàn nàn nếu bạn đặt phương thức không tồn tại (hoặc có chữ ký sai, v.v.) sụp đổ trong thời gian chạy trong trường hợp đó - vì vậy hãy thận trọng.
+0

Tuyệt vời! Tôi không biết về vĩ mô và google không hiển thị nhiều. Bạn có bất kỳ tham chiếu nào từ tài liệu của Apple không? – Yariv

+4

Đẹp? Điều này là khủng khiếp tiết và lộn xộn. Đây có thực sự là những gì bạn cần làm không? Tôi đã gặp phải vấn đề tương tự, và thậm chí cả táo cũng phải cố gắng làm điều gì đó tốt hơn thế này. Tôi sẽ từ bỏ điều này và quay trở lại mục tiêu c, điều này là không hợp lý! +1 để đăng nội dung nào đó thực sự hoạt động (sau giờ tìm kiếm). –

+3

Theo tài liệu của Apple "Bạn vẫn có thể sử dụng các phương thức và thuộc tính Swift được đánh dấu bằng công cụ sửa đổi nội bộ từ bên trong phần Objective-C của khung công tác của bạn, miễn là chúng được khai báo trong một lớp kế thừa từ một lớp Objective-C", nếu lớp nhanh có nguồn gốc từ một lớp objc khác, nó sẽ có sẵn trong mã objc. Tôi có vấn đề tương tự và tôi đã đánh dấu lớp học nhanh chóng của tôi với @objc và nó kế thừa từ NSObject nhưng vẫn không có sẵn trong mã objc. – puru020

3

Đối với tôi, tính năng này chỉ hoạt động bằng cách kiểm tra: "Chỉ cho phép API tiện ích ứng dụng".Bạn tìm thấy nó bằng cách vào thiết lập dự án, chọn mục tiêu của bạn và sau đó nó nằm trong tab General trong Deployment Info.

Ai đó có thể giải thích cho tôi, tại sao điều này giải quyết được sự cố?

+0

Tôi yêu bạn! LOL. Đó là nơi duy nhất trên trái đất tìm ra câu trả lời để vượt qua giới hạn ngu ngốc này. Không cần phải có khung để trưng bày các lớp Swift của nó cho người tiêu dùng API chỉ để có thể tương tác với mã ObjC nội bộ! – nobre

+0

Hãy cẩn thận khi thử tùy chọn này! Nó sẽ liệt kê các lớp và các phương thức trong tiêu đề được tạo tự động. Chỉ sử dụng nó nếu bạn không quan tâm đến việc giữ riêng tư. – Amit

+0

Nhưng với điều này kiểm tra, sẽ có một bó Cocoa API mất tích. – Martin

Các vấn đề liên quan