2011-09-07 47 views
22
  1. Khi tôi sử dụng từ extern trước một phương pháp hoặc khai báo biến, tôi làm cho nó toàn cầu và do đó có thể đọc/ghi/có thể sử dụng trên toàn bộ dự án?3 câu hỏi về extern sử dụng trong một dự án Objective-C

  2. Nếu tôi sử dụng extern trước từ khóa, có khả năng nó vẫn không thể truy cập được bởi một phần của dự án của tôi không? Ví dụ, chỉ bởi các lớp con .. chẳng hạn như khi tôi sử dụng "bảo vệ".

  3. extern là từ khóa C, phải không? Có tương đương trong Objective-C không? Tôi thực sự không hiểu tại sao họ sử dụng một từ khóa C trong một dự án Objective-C.

nhờ

+3

Objective-C là một superset của C. Vì vậy, các từ khóa C áp dụng. – Mat

+0

câu hỏi hay .. – Krishnabhadra

+0

@ Tôi biết, nhưng quan điểm của tôi là: không phải khách quan-c cung cấp các từ khóa riêng của mình để khai báo các phương pháp và biến số globals? – aneuryzm

Trả lời

37

1) bạn đang xác định mối liên hệ của nó. liên kết bên ngoài cho phép bạn hoặc bất kỳ khách hàng nào tham khảo biểu tượng.

liên quan đến các biến toàn cầu: nếu biến có thể thay đổi và/hoặc cần xây dựng phù hợp, thì bạn nên xem xét các phương pháp hoặc chức năng cho đối tượng này. Ngoại trừ đáng chú ý này được NSString hằng:

// MONClass.h 
extern NSString* const MONClassDidCompleteRenderNotification; 
// MONClass.m 
NSString* const MONClassDidCompleteRenderNotification = @"MONClassDidCompleteRenderNotification"; 

2) không có trường hợp từ khóa extern ảnh hưởng đến tầm nhìn (công/bảo vệ/private/gói). để sử dụng ký hiệu (ví dụ: hàm hằng số hoặc hàm C), chỉ cần bao gồm tiêu đề được khai báo.

hơi khó hiểu nếu bạn mới sử dụng ngôn ngữ: đặt các khai báo extern C (hằng số, hàm) ở giữa @interface ... @end sẽ không thay đổi phạm vi của nó:

@interface MONClass : NSObject 

extern const size_t MaximumThreads; 

@end 

có cùng phạm vi (toàn cầu) và tầm nhìn (công cộng) như:

@interface MONClass : NSObject 

@end 

extern const size_t MaximumThreads; 

để nó thực sự làm cho không có ý nghĩa để đặt lớp liên quan hằng C hoặc các chức năng của bạn trong @[email protected]@[email protected]. tôi khuyên bạn nên đặt những trong tiêu đề tương tự như giao diện, bên ngoài @interface/@end@implementation/@end và tiền tố tên với lớp nó gắn liền với, như vậy:

@interface MONClass : NSObject 

@end 

extern const size_t MONClassMaximumThreads; 
// MONClass.m 
const size_t MONClassMaximumThreads = 23; 

và nếu bạn muốn điều đó liên tục được tin, chỉ cần khai báo và xác định nó như sau:

// MONClass.m 
static const size_t MONClassMaximumThreads = 23; 

@implementation MONClass 

@end 

thật không may, không có cách nào đơn giản hoặc phổ biến để bảo vệ liên tục với objc này.

cuối cùng, bạn cũng có thể sử dụng phương pháp lớp nếu số lượng cần thay đổi theo từng lớp:

@interface MONMammal : NSObject 
+ (NSUInteger)numberOfLegs; 
@end 

@implementation MONDog 
+ (NSUInteger)numberOfLegs { return 4; } 
@end 
@implementation MONHuman 
+ (NSUInteger)numberOfLegs { return 2; } 
@end 

3) có, giữa các ngôn ngữ khác. ví dụ: nếu bạn sử dụng extern const int Something trong bản dịch C++, bản dịch C++ sẽ tìm kiếm Something được khai báo dưới dạng biểu tượng extern C++. không có sự thay thế trong objc; objc là một superset của C và kế thừa tất cả các chức năng của C. sử dụng extern cũng được hình thành và bạn cũng có thể tìm thấy nó trong các khuôn khổ mà bạn sử dụng (ví dụ: Foundation). họ sử dụng nó bởi vì họ cần phải xác định liên kết. objc không cung cấp thay thế, có lẽ vì nó không yêu cầu thay thế hoặc gia hạn.

để tránh điều này, bạn chỉ cần sử dụng một #define như thế này:

#if !defined(__cplusplus) 
#define MONExternC extern 
#else 
#define MONExternC extern "C" 
#endif 

MONExternC const size_t MONClassMaximumThreads; 
+2

A vài ghi chú từ quan điểm của khai báo lớp: wrt 1), không có phương thức 'extern' trong Objective-C; wrt 2) và liên quan đến 1), nó không áp dụng cho các cấu trúc phân lớp. –

+0

@Bavarious hmm ... tôi đã không chỉ định rằng các phương thức là extern, chỉ * xuất *. tôi sẽ đọc lại nó vào ngày mai - tôi khá mệt mỏi. nó có thể chỉ được diễn đạt kém :) cảm thấy tự do để chỉnh sửa nó, nếu bạn thích. – justin

+0

Chỉ cần (hy vọng!) Làm cho nó một chút rõ ràng hơn cho OP (và, sau 24 giờ tỉnh táo, tôi thậm chí không xem xét trả lời). –

16

extern không có nghĩa là "toàn cầu", nó có nghĩa là "định nghĩa ở nơi khác". Nó được sử dụng để báo cho trình biên dịch rằng một biến hoặc hàm tồn tại (trong một tệp hoặc thư viện đối tượng khác), để nó không được khiếu nại về nó và trình liên kết sẽ được cung cấp với tệp hoặc thư viện đối tượng đó.

Kết quả là extern ngụ ý rằng mục tiêu là toàn cầu.

Mục tiêu-C chỉ là một siêu sao của C. Mọi thứ có sẵn trong C cũng có sẵn trong Mục tiêu-C, với cú pháp và ngữ nghĩa tương tự. Không có cấu trúc của C được định nghĩa theo cách khác trong Objective-C.

+0

Cảm ơn. Vì vậy, tôi luôn luôn cần phải nhập khẩu các tiêu đề có chứa các tuyên bố extern, nếu tôi muốn sử dụng phương pháp extern/biến? – aneuryzm

+0

Nói cách khác, tôi có thể lưu trữ các biến/phương thức bên ngoài của tôi trong một lớp và nhập tiêu đề của nó khi tôi cần sử dụng chúng không? Như thay thế không thể chỉ sử dụng các phương pháp tĩnh hoặc các biến từ một singleton? – aneuryzm

+1

'extern' không áp dụng cho các phương thức hoặc các biến mẫu, nó áp dụng cho các hàm hoặc các biến nằm ngoài phạm vi của một lớp. – mouviciel

0

điểm 3: Có bạn có thể sử dụng FOUNDATION_EXPORT trong C mục tiêu mà là một vĩ mô mà giải quyết đến từ khóa khác nhau tùy thuộc nếu biên dịch C hoặc C++

Thông tin thêm ở đây về sự khác biệt: "FOUNDATION_EXPORT" vs "extern"