2012-02-20 8 views
28

Trong điều kiện nào là @synthesize tự động trong Mục tiêu-c?Dưới những điều kiện nào là @synthesize tự động trong Objective-c?

Có lẽ khi sử dụng LLVM 3.0 trở lên? Từ đọc xung quanh mạng có vẻ như @synthesize là không cần thiết bắt đầu bằng Xcode 4. Tuy nhiên, tôi đang sử dụng Xcode 4 và nhận cảnh báo khi tôi không @synthesize một thuộc tính.

Một số câu trả lời cho Why don't properties get automatically synthesized dường như hàm ý @synthesize có thể được bỏ qua tại một số điểm trong một số trường hợp.

Another (old) reference gợi ý rằng @synthesize có thể tự động tại một số điểm trong tương lai.

+5

Bạn có liên kết cho nơi @synthesize được mô tả là không cần thiết không? – bneely

+0

Có lẽ ông đã nhìn thấy một số thông tin về hiện tại dưới NDA Xcode 4.4 và đã trở nên bối rối về số phiên bản. –

+1

@bneely đã thêm một liên kết. Có lẽ tôi đang hiểu sai "@synthesize là tự động trong các phiên bản mới nhất của trình biên dịch LLVM 2.0". – SundayMonday

Trả lời

11

Kể từ Xcode 4.4, nếu bạn không viết @synthesize hoặc @dynamic cho thuộc tính. trình biên dịch hoạt động như thể bạn đã viết @synthesize property = _property.

Trước Xcode 4.4, bạn phải thực hiện một trong những điều sau cho mỗi thuộc tính hoặc trình biên dịch khác sẽ đưa ra cảnh báo và bạn sẽ gặp lỗi thời gian chạy. Trong Xcode 4.4 hoặc mới hơn, bạn có thể thực hiện bất kỳ điều nào sau đây thay vì để trình biên dịch tự động tổng hợp các trình truy cập thuộc tính và biến mẫu.

  1. Sử dụng chỉ thị @synthesize.
  2. Sử dụng chỉ thị @dynamic và bằng cách nào đó cung cấp trình khởi động thuộc tính và (nếu cần) thiết lập khi chạy.
  3. Ghi rõ phương thức getter thuộc tính và, nếu thuộc tính là readwrite, phương thức setter của thuộc tính.

Lưu ý rằng bạn có thể sử dụng @synthesize chỉ thị (hoặc @dynamic chỉ thị) và cũng cung cấp một cách rõ ràng các phương pháp getter và/hoặc setter. Nhưng @synthesize cung cấp cho họ nếu bạn bỏ qua chúng.

+2

Nếu bạn cung cấp BOTH the getter và setter, sau đó bạn mất tự động ivar, phải không? –

23

Do clang 3.2 (khoảng tháng 2 năm 2012), "tổng hợp mặc định" (hoặc "tổng hợp thuộc tính tự động") của thuộc tính Objective-C được cung cấp theo mặc định. Về cơ bản nó được mô tả trong bài đăng trên blog mà bạn đã đọc ban đầu: http://www.mcubedsw.com/blog/index.php/site/comments/new_objective-c_features/ (ngoại trừ bài đăng đó mô tả tính năng là "đã bật, rồi tắt"; tôi không biết đó có phải là vấn đề với Xcode hay không. trên câu hỏi).

Theo tôi biết, trường hợp duy nhất trong đó các thuộc tính sẽ không được tổng hợp mặc định trong clang 3.2 là khi các thuộc tính đó được kế thừa từ giao thức. Dưới đây là một ví dụ:

#import <Foundation/Foundation.h> 

@protocol P 
@property int finicky; 
@end 

@interface A : NSObject <P> 
@property int easygoing; 
@end 

@implementation A 
@end 

int main() { A *a = [A new]; a.easygoing = 0; a.finicky = 1; } 

Nếu bạn biên dịch ví dụ này, bạn sẽ nhận được một cảnh báo:

test.m:11:17: warning: auto property synthesis will not synthesize property 
     declared in a protocol [-Wobjc-protocol-property-synthesis] 
@implementation A 
       ^
test.m:4:15: note: property declared here 
@property int finicky; 
      ^
1 warning generated. 

và nếu bạn chạy nó, bạn sẽ nhận được một lỗi từ runtime:

objc[45820]: A: Does not recognize selector forward:: (while forwarding setFinicky:) 
Illegal instruction: 4 
4

Bạn có thể tắt cảnh báo tổng hợp bằng cách nhấp vào tên dự án trong Project Navigator ở bên trái, sau đó nhấp vào All Cobined in Build Settings và sau đó tìm kiếm tổng hợp. Điều đó nên được đặt thành Không.

+0

Thực ra đây là câu trả lời đúng duy nhất, một câu trả lời cũ. Phần còn lại đi sâu. Hãy chắc chắn kiểm tra cài đặt của tất cả các mục tiêu của bạn, nếu bạn có nhiều – doozMen

12

Từ tài liệu New Features in Xcode 4.4:

@properties Objective-C được tổng hợp theo mặc định khi không được thực hiện một cách rõ ràng.

Vì vậy, @synthesize tự động theo mặc định bắt đầu từ Xcode 4.4 với trình biên dịch LLVM 4.0.

+3

Lưu ý rằng tổng hợp tự động không được hỗ trợ cho Mac OS X. 32 bit – ThomasW

7

Ngoài ra, tổng hợp sẽ không tự động nếu bạn đã triển khai setter AND getter theo cách thủ công. Vì vậy, nếu bạn tự hỏi tại sao bạn không thể truy cập _someVariable, khi khai báo @property (...) SomeType someVariable, thì đó là vì bạn đã triển khai phương thức setSomeVariable: và someVariable.