2011-10-28 29 views
15

Nó có thể đơn giản câu hỏi, nhưng tại sao việc thực hiện Nghị định thư NSCopying trong lớp học của tôi, tôi nhận được == khu nilTại sao khu vực luôn luôn là nil trong khi triển khai NSCopying?

- (id)copyWithZone:(NSZone *)zone 
{ 
    if (zone == nil) 
     NSLog(@"why this is allways nil"); 

    (...) 
} 

này được gọi là sử dụng phương pháp này cho mảng bản với các đối tượng.

[[NSArray alloc] initWithArray:myArray copyItems:YES]]; 

Trả lời

25

Câu trả lời của Kevin và Robin là chính xác nhất. Câu trả lời của Oscar khá gần đúng. Nhưng không phải tài liệu Gnustep cũng như các lý do của logancautrell về sự tồn tại của các vùng là khá chính xác.

Vùng ban đầu được tạo - NXZone đầu tiên, sau đó là NSZone - để đảm bảo rằng các đối tượng được phân bổ từ một vùng sẽ tương đối liền kề trong bộ nhớ, điều đó là đúng. Khi nó quay ra, điều này không làm giảm số lượng bộ nhớ một ứng dụng sử dụng; nó kết thúc tăng lên một chút, trong hầu hết các trường hợp.

Mục đích lớn hơn là có thể tiêu diệt hàng loạt đối tượng. Ví dụ: nếu bạn tải một tài liệu phức tạp vào một ứng dụng dựa trên tài liệu, hãy xé xuống biểu đồ đối tượng khi tài liệu được đóng lại thực sự có thể khá đắt tiền.

Vì vậy, nếu tất cả các đối tượng cho một tài liệu đã được phân bổ từ một khu vực đơn siêu dữ liệu phân bổ cho vùng đó là cũng trong khu vực đó, sau đó phá hủy tất cả các đối tượng liên quan đến tài liệu sẽ rẻ như đơn giản là phá hủy khu vực (vốn thực sự rẻ - "ở đây, hệ thống, có các trang này trở lại" - một cuộc gọi chức năng).

Điều này tỏ ra không khả thi. Nếu một tham chiếu đến một đối tượng trong vùng bị rò rỉ ra khỏi vùng, thì ứng dụng của bạn sẽ đi BOOM ngay sau khi tài liệu bị đóng và không có cách nào để đối tượng nói bất cứ điều gì đang đề cập đến nó. Thứ hai, mô hình này cũng đã trở thành con mồi cho vấn đề "khan hiếm tài nguyên" nên thường gặp phải trong hệ thống GC'd. Đó là, nếu đồ thị đối tượng của tài liệu được lưu trữ trên các tài nguyên không nhớ, thì không có cách nào để dọn sạch các tài nguyên đã nói một cách hiệu quả trước khi hủy vùng.

Cuối cùng, sự kết hợp của không đủ gần đạt được hiệu suất (tần suất bạn thực sự đóng tài liệu phức tạp) với tất cả các vùng dễ vỡ được thêm vào làm cho một ý tưởng tồi. Tuy nhiên, quá muộn để thay đổi các API và chúng tôi còn lại với các dấu tích.

+0

Tuyệt vời, tôi đã hy vọng bạn sẽ trả lời câu hỏi này. Lưu ý phụ, liệu tài liệu này có được viết trong tài liệu của Apple tại bất kỳ thời điểm nào không? Tất cả những gì tôi có thể tìm thấy hôm nay là các phương pháp nền tảng của NSZone *. – logancautrell

+3

Hãy thoải mái @bbum tôi trên Twitter nếu có những câu hỏi như thế này mà bạn muốn thu hút sự chú ý của tôi. Sự tiến hóa của ngôn ngữ (và hệ điều hành) là hấp dẫn, thực sự. Nếu nó đã từng được ghi lại, nó có thể còn sót lại trong những ngày Rhapsody. Tôi không nghĩ rằng khu vực đã từng được đề xuất trong phiên bản Mac OS X phù hợp. – bbum

+1

Tôi đánh giá cao điều đó, bài đăng của bạn được đánh giá cao vì vị trí và lịch sử duy nhất của bạn. Tôi muốn nhiều kỹ sư của Apple dành thời gian ở đây! – logancautrell

1

Vùng là di sản từ những ngày cũ khi máy tính có RAM từ 8 megabyte trở xuống.

Kiểm tra này ra (Allocation 3.1.2 Bộ nhớ và khu):

http://www.gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_3.html

Ngoài ra còn có một cuộc thảo luận tốt về điều này trên trên builder cacao (cũng nó đã được trên mailing list cacao dev) từ khoảng 10 năm trước. Đây chính xác là những gì @bbum đang nói.

http://www.cocoabuilder.com/archive/cocoa/65056-what-an-nszone.html

Rõ ràng đây từng được ghi nhận trong các tài liệu của Apple, nhưng nó đã được thay đổi tại một số điểm từ 2007/06/06.

http://www.cocoadev.com/index.pl?NSZone

1

NSZone tại là một lớp không có giấy tờ vì nó là khá cũ, mục đích của nó là để phân bổ đối tượng trên heap bằng cách sử dụng cùng một bộ trang bộ nhớ ảo. Tuy nhiên, nó hầu như không được sử dụng nữa, nhưng vì nó đã được sử dụng trước đó, tham số đó vẫn còn đó cho khả năng tương thích ngược.

3

NSZone không được dùng nữa từ lâu. Thực tế là nó vẫn còn trong chữ ký phương thức (ví dụ: +allocWithZone:-copyWithZone:) dành cho khả năng tương thích ngược.

+1

nếu copyWithZone không được dùng nữa (những gì không được đề cập trong định nghĩa giao thức NSCopying), cách triển khai NSCopying với copyWithZone bắt buộc: trong những ngày này? – Marcin

+3

'-copyWithZone:' không được chấp nhận. 'NSZone' là. Chỉ cần bỏ qua đối số vùng. –

4

Vùng NULL chỉ có nghĩa là 'sử dụng vùng mặc định'. Vùng không được sử dụng bởi thời gian chạy Objective C hiện đại nữa và không thể được sử dụng với ARC.

Xem documentation

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