2010-07-18 28 views
6

Tôi chọn ObjC và Cocoa, đây cũng là bước đột phá nghiêm trọng đầu tiên của tôi vào lập trình nói chung.InitWith Methods vs. Method Methods

Tôi đang gặp sự cố với sự khác biệt giữa các phương thức initWith, được gọi trên trường hợp và phương thức nhà máy, được gọi trên lớp.

Thứ nhất, tại sao chúng được gọi là phương pháp "nhà máy" và có thuật ngữ thích hợp cho những gì tôi đã gọi là phương thức "InitWith" không?

Thứ hai, sự khác biệt chức năng là gì? Nó chỉ là các hàm ý quản lý bộ nhớ (các phương thức factory trả về một đối tượng autoreleased)?

Ví dụ: sự khác biệt thực sự giữa [NSString stringWithString: (NSString*)aString][[NSString alloc] initWithString: (NSString*)aString] là gì?

Trả lời

5

Sự khác biệt giữa các phương pháp được mô tả trong ca cao object ownership policy. Bạn sở hữu đối tượng được trả về từ -initWithString: và vì vậy phải giải phóng nó, nhưng bạn không sở hữu đối tượng được trả về từ + stringWithString và do đó không cần phải giải phóng nó (hơn nữa, nếu bạn muốn giành quyền sở hữu nó, bạn phải giữ lại nó).

Phương thức của nhà máy được gọi là vì chúng trả về đối tượng đã tạo cho bạn, thường với các tham số bạn cung cấp được sử dụng để định cấu hình đối tượng, để thuận tiện cho lập trình viên.

0

On dụ bạn

[[NSString alloc] initwithString: (NSString  
*)aString]; 

Khi bạn làm một alloc bạn đang đặt một không gian cho các String trong bộ nhớ do đó alloc. sau đó bạn yêu cầu nó khởi tạo với chuỗi bằng aString. (NSString *) là một định danh cho kiểu đối tượng, do đó bạn đang nói aString được khai báo là một NSString.

Tôi thường làm điều gì đó như

NSString * aString = @"String value"; 

tuyên bố những gì aString bằng.

Nếu bạn alloc một cái gì đó vào bộ nhớ để quản lý nó, bạn sẽ cần phải phát hành nó tại thời điểm chính xác chẳng hạn như phần

-(void) dealloc {} 

mã của bạn

Mọi thứ về NSString có thể được giải thích trong tài liệu này từ Apple NSString

+0

Điều này xảy ra với cả hai bạn, Ruglud và Audacitor: Bạn không cần phải bao gồm '(NSString *)' khi gửi thông điệp 'initWithString:'. Chỉ khai báo của phương thức cần nó (để chỉ định kiểu phương thức mong đợi). Khi bạn đưa nó vào như một phần của một thông điệp, bạn đang truyền giá trị 'aString' tới' NSString * '.Nếu 'aString' là' NSString * ', thì điều này không có gì và không cần thiết; nếu nó là cái gì khác, sau đó các diễn viên sẽ vẫn không làm gì hữu ích: Nó sẽ đóng cửa trình biên dịch, nhưng bạn sẽ sụp đổ tại thời gian chạy. –

0

Sự khác biệt chính là

[NSString stringWithString: 
    (NSString*)aString] 

trả về một chuỗi autoreleased mà quản lý bộ nhớ bạn không cần phải lo lắng về việc, trong khi

[[NSString alloc] initWithString: 
    (NSString*)aString] 

trả về một chuỗi mà bạn có trách nhiệm phát hành. Về cơ bản trước đây là một phím tắt cho sau này, cộng với autorelease.

+1

, "quản lý bộ nhớ mà bạn không cần phải lo lắng" không hoàn toàn là toàn bộ câu chuyện và có thể dẫn đến một kẻ lạc đường mới ... Ví dụ: nếu bạn chỉ định kết quả cho biến mẫu (1) thì bạn ' sẽ muốn giữ lại kết quả từ một phương thức lớp hoặc bạn sẽ thấy rằng khi bạn truy cập vào cá thể của bạn var nó sẽ biến mất. Đây là một sai lầm kinh điển cho những người mới đến ObjC/Cocoa. (1) một biến mẫu không phải là thuộc tính với bộ tổng hợp được thiết lập để giữ lại thông qua thuộc tính thuộc tính. – Dad

+1

Một sai lầm phổ biến khác là gây nhầm lẫn các biến mẫu với các thuộc tính. Chính sách quản lý bộ nhớ (ví dụ: 'giữ lại') mà bạn khai báo cho thuộc tính không ảnh hưởng đến biến cá thể; các phép gán cho biến cá thể luôn luôn xảy ra mà không có tác dụng phụ, bao gồm cả không có sự cố định hoặc bản sao. Do đó, khi chỉ định cho một ngà voi, bạn cần giữ lại hoặc tự sao chép giá trị. Chỉ gán cho một tài sản có thể làm điều đó cho bạn. –

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