2009-02-25 32 views
16

Tôi đang tìm kiếm ứng dụng mẫu của Apple EditableDetailView và nhận thấy rằng trong một trong các trình điều khiển của chúng, chúng đang thiết lập một thể hiện thuộc tính NSString với (nonatomic, copy). Khi nào một người sử dụng bản sao thay vì giữ lại? Đây có phải là để họ có thể tạo một bản sao duy nhất mà không ảnh hưởng đến dữ liệu hiện có không?NSString @property, sử dụng bản sao thay vì giữ lại

+2

Đề xuất là sử dụng bản sao cho các lớp học là một phần của cụm lớp có cặp có thể thay đổi/không thay đổi được; chẳng hạn như 'NSString' /' NSMutableString' 'NSArray' /' NSMutableArray' 'NSDictionary' /' NSMutableDictionary' 'NSSet' /' NSMutableSet', xem câu trả lời của @ Abizern [HERE] (http://stackoverflow.com/questions/4995254/nsmutablestring-as-retain-copy). – Kjuly

Trả lời

38

Có, nó sao cho nó có thể tạo một bản sao duy nhất mà không ảnh hưởng đến dữ liệu hiện có. Các setters tổng hợp về cơ bản giống như thế này:

// For @synthesize(nonatomic, retain) foo: 
- (void) setFoo(NSFoo *theFoo) 
{ 
    [theFoo retain]; // retain new value 
    [foo release]; // release old value, if any 
    foo = theFoo;  // assign new value 
} 

// For @synthesize(nonatomic, copy) foo: 
- (void) setFoo(NSFoo *theFoo) 
{ 
    NSFoo* newFoo = [theFoo copy]; // make copy 
    [foo release]; // release old value, if any 
    foo = newFoo; // assign new value 
} 

Lưu ý thứ tự của các hoạt động ở đây là rất quan trọng - giá trị mới phải được giữ lại/sao chép trước khi giá trị cũ được phát hành, trong trường hợp tự chuyển nhượng. Nếu bạn phát hành đầu tiên và sau đó gán tài sản cho chính nó, bạn có thể deallocate các giá trị một cách tình cờ. Cũng lưu ý rằng nếu giá trị cũ là nil, gửi tin nhắn release là ok, vì việc gửi tin nhắn đến một đối tượng nil được cho phép rõ ràng và không làm gì cả.

Lựa chọn giữ lại so với sao chép chỉ xác định xem thuộc tính của đối tượng có cùng giá trị với những gì bạn đang đặt. Xét đoạn mã sau:

// suppose the 'foo' property is declared 'retain' and the 'bar' property is 
// declared 'copy' 
NSFoo *foo = ...; 
NSBar *bar = ...; 
someObject.foo = foo; 
someObject.bar = bar; 
[foo changeInternalState]; // someObject.foo also changes, since it's the same object 
[bar changeInternalState]; // someObject.bar does NOT change, since it's a copy 
+0

có thể có lỗi đánh máy trong dòng cuối cùng của bạn. nơi //someObject.foo KHÔNG ... nên //someObject.bar KHÔNG –

+0

Để có thể gọi 'copy' trên đối tượng Lớp tùy chỉnh, bạn phải ghi đè phương thức' copyWithZone: '. – thesummersign

3

Hãy nhớ rằng có một NS Biên Đổi String. Sẽ rất tệ nếu có thể thay đổi nội dung của chuỗi mà một số đối tượng khác sở hữu (bằng cách xóa một nửa số ký tự của nó), đặc biệt nếu bạn không nhận ra mình đang ảnh hưởng đến một đối tượng khác. Vì vậy, nó là tốt đẹp cho các đối tượng khác để làm cho bản sao của riêng mình.

Bạn có thể nói “tốt, tại sao tôi không sao chép chuỗi trước khi gán nó ở đó?”. Có lẽ đối tượng muốn một chuỗi có thể thay đổi và bạn không thể thay đổi được. Nếu bạn phải sao chép chuỗi đầu tiên, sau đó bạn phải tìm kiếm loại chuỗi nó muốn trong tài liệu hoặc tiêu đề của nó, sau đó thực hiện đúng loại bản sao (mọi thời điểm). Bằng cách này, bạn chỉ cần nói other.string = myString và nó làm cho bất kỳ loại bản sao nó muốn-bạn không phải lo lắng về nó.

0

(Đối với một số lý do, bài này được xuất hiện trên các câu hỏi theo dõi tôi đang cố gắng để trả lời) Re:

bạn đã có nghĩa là tôi phải sao chép 'các foo' đối tượng trước khi thả 'foo' ?? nhưng whats vấn đề nếu tôi relaese 'foo' trước khi sao chép 'các foo' ?? bởi vì họ là hai khác nhau đối tượng tôi có thể không hiểu tại sao phát hành một ảnh hưởng khác !!!!

Hầu hết thời gian, bạn là chính xác. Nếu chúng là, trên thực tế, hai đối tượng riêng biệt, nó sẽ không thành vấn đề. Vấn đề nằm ở khả năng bạn đang gán cùng một đối tượng vào chính nó. Nếu bạn muốn nói

[myObject setFoo: moof]; 
[myObject setFoo: moof]; 

Sau đó, lần thứ hai bạn đã thực hiện, bạn sẽ phát hành trước khi bạn sao chép. Trong thời điểm can thiệp, có thể là nếu số lượng giữ lại của moof là 0 thì moof sẽ bị xóa, và bạn sẽ không có gì để sao chép trong bước tiếp theo. Foo bây giờ sẽ là không.

Điều này có khả năng xảy ra không? Có lẽ nhiều hơn bạn nghĩ. Có chắc chắn là khi người dùng có thể nhấp vào nút "cập nhật" hai lần, ví dụ.

Tôi hy vọng điều này là dễ hiểu và hữu ích.

+1

Stack Overflow là một trang hỏi và trả lời, không phải là diễn đàn. Câu trả lời, trong đó cả câu hỏi này và "câu hỏi" bạn muốn phản hồi, được sắp xếp theo phiếu bầu theo mặc định. Của bạn có 0 và câu trả lời khác (mà bây giờ đã bị xóa) kết thúc ở -3, do đó, bạn xuất hiện cao hơn (cho những người trong chúng ta với đủ nghiệp lực để xem khác ở tất cả). Cách đúng đắn sẽ là bình luận về câu trả lời khác, nhưng điều đó đòi hỏi 50 điểm danh tiếng mà bạn không có. (Thêm câu trả lời của bạn quá sâu và được định dạng phong phú để phù hợp với nhận xét.) Không có cách nào đúng trong trường hợp của bạn. –

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