2012-05-03 41 views

Trả lời

13

bạn có thể dừng việc tạo ra các biến dụ hoàn toàn

Không, bạn không thể (theo nghĩa). Những gì bạn có thể làm là ngừng khai báo chúng nếu bạn có tài sản. Nếu bạn tổng hợp một thuộc tính và bạn chưa khai báo instvar, nó sẽ được khai báo cho bạn, vì vậy bạn đang tạo một biến cá thể, không rõ ràng.

họ vẫn phục vụ mục đích mà các thuộc tính sẽ không phù hợp?

Nó từng là lời khuyên để tạo thuộc tính cho mọi thứ vì có các thuộc tính tổng hợp hầu như tất cả đều giữ lại và giải phóng cho bạn. Tuy nhiên, với ARC lý do cho việc sử dụng các thuộc tính để bọc quản lý bộ nhớ đã biến mất. Lời khuyên bây giờ (cho ARC) là, tôi tin rằng, sử dụng các thuộc tính để khai báo giao diện bên ngoài của bạn, nhưng sử dụng các biến cá thể trực tiếp trong đó biến là một phần của trạng thái bên trong của đối tượng.

Đó là lý do chính đáng để áp dụng ARC: các thuộc tính trở lại mục đích thực sự của chúng chỉ là một phần của API của lớp và không còn cần thiết để sử dụng chúng như một cách hack để ẩn công việc quản lý bộ nhớ.

Sửa

Một điều nữa: bây giờ bạn có thể khai báo các biến Ví dụ trong @implementation do đó bây giờ không cần phải bị rò rỉ bất kỳ chi tiết thực hiện trong @interface. tức là

@implementation MyClass 
{ 
    NSString* myString; 
} 
// method definitions 
@end 

Và tôi cũng chắc chắn nó cũng hoạt động trong danh mục. - xem nhận xét bên dưới

+3

bạn không thể thêm ivars và thuộc tính vào danh mục, vì thời gian chạy objc chỉ cho phép thêm ngà trong quá trình đăng ký lớp học. Bạn không thể thay đổi bố cục bộ nhớ của một lớp sau khi nó được đăng ký với thời gian chạy. –

+0

bạn * có thể *, tuy nhiên thêm ivars vào một phần mở rộng lớp (liên quan chặt chẽ, nhưng khác với một thể loại) – Sean

+1

@ Jonathan Cichon: Cảm ơn, chỉ cần thử nó và nó chỉ ra bạn là chính xác về biến thể hiện nhưng sai về tài sản . Bạn có thể thêm các thuộc tính nhưng bạn không thể 'tổng hợp' chúng. – JeremyP

0

Câu hỏi này đã được giải quyết trước khi here

Khi bạn sử dụng synthesize các biến dụ được xử lý và khởi tạo cho bạn. Nếu bạn đang sử dụng Lion với phiên bản XCode mới cũng hãy xem các thuộc tính khác nhau trong ARC in Transitioning to ARC

+1

Tôi không nghĩ đó là cùng một câu hỏi, nhưng tôi đã cập nhật câu hỏi của mình để hy vọng làm cho nó rõ ràng hơn. – Besi

0

bạn luôn có thể truy cập các thuộc tính từ bên ngoài. Vì vậy, nếu bạn muốn một biến chỉ được đọc từ bên trong một lớp, bạn vẫn phải khai báo một iVar. Ngoài ra, truy cập vào thanh công khai với object->ivar sẽ nhanh hơn một chút so với sử dụng cuộc gọi phương thức.

+2

Điều này không đúng. Nếu bạn khai báo thuộc tính trong tệp .m thì sao? – Martin

+0

bạn phải, bạn có thể ẩn hoàn toàn thuộc tính, nhưng hơn bạn không thể truy cập nó từ bên ngoài tệp m của bạn, ví dụ như một lớp con. –

+1

@Martin: Vì thuộc tính được triển khai như một cặp phương thức, nó luôn sẵn có vào thời gian chạy bất kể nó được khai báo ở đâu. – JeremyP

9

Tôi khuyên bạn nên khai báo mọi thứ dưới dạng thuộc tính và tránh hoàn toàn thủ công. Không có bất lợi nào trong việc tạo ra các cây ngà voi theo cách thủ công. Khai báo các thuộc tính công khai trong tiêu đề @interface, khai báo các thuộc tính riêng tư trong một phần mở rộng lớp riêng tư trong tệp .m của bạn.

Đối với một số điểm của JeremyP, việc sử dụng nội bộ của người truy cập vẫn có giá trị đáng kể trong ARC, mặc dù quản lý bộ nhớ không còn là mối quan tâm đáng kể. Nó đảm bảo rằng KVO hoạt động tốt, subclasses tốt hơn, hỗ trợ tùy chỉnh setters (đặc biệt là cho những thứ như NSTimer), hỗ trợ tùy chỉnh getters (chẳng hạn như cho instantiation lười biếng), vv Nó là cực kỳ dễ bị lỗi để có một kết hợp của accessors và ivars. Thật dễ dàng để quên đi những gì bạn cần truy cập theo cách nào.Nhất quán là dấu hiệu của ObjC tốt.

Nếu bạn hoàn toàn phải khai báo một ivar vì lý do nào đó, thì bạn nên làm điều đó trong khối @implementation như ghi chú JeremyP.


UPDATE (Oct-2013):

Apple's guidance (Từ Lập trình với Objective-C: Encapsulating dữ liệu):

Hầu hết các thuộc tính này được hỗ trợ bởi biến Instance

Nói chung, bạn nên sử dụng các phương thức accessor hoặc cú pháp chấm để truy cập thuộc tính ngay cả khi bạn đang truy cập các thuộc tính của đối tượng từ bên trong nó thực hiện riêng, trong trường hợp này bạn nên sử dụng self:

...

Trường hợp ngoại lệ cho quy tắc này là khi viết khởi, deallocation hoặc accessor tùy chỉnh phương pháp, như mô tả sau trong phần này.

+0

KVO không quan trọng đối với nội dung chỉ có nội bộ. Không phải là phân lớp phụ. Không có gì là một phần của việc thực hiện một lớp nên bị rò rỉ, ngay cả với các lớp con. Đây là dấu hiệu của OOP tốt. – JeremyP

+0

KVO (mặc dù tự quan sát đôi khi được sử dụng), vì bạn thường yêu cầu người truy cập vào thuộc tính riêng (thuyết minh lười biếng, an toàn luồng, vv) và sử dụng chúng đơn giản và rẻ tiền, bạn nên luôn sử dụng chúng ngoại trừ khi có một lý do mạnh mẽ không để (tức là dealloc). Đôi khi việc sử dụng ivars và đôi khi sử dụng accessors là dễ bị lỗi và khó kiểm toán tính chính xác. –

+0

Làm thế nào để bạn làm instantiation lười biếng mà không có một biến dụ? Tôi sẽ lặp lại: dòng chính thức như được báo cáo trong danh sách Apple là sử dụng các biến mẫu cho trạng thái nội bộ khi bạn có ARC nhưng phải sử dụng các thuộc tính cho mọi thứ nếu bạn đang sử dụng đếm tham chiếu truyền thống. – JeremyP

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