Tôi có một đoạn mã trong ứng dụng iPhone, loại bỏ tất cả các bản xem trước khỏi lớp con UIView. Có vẻ như sau:Sự khác biệt về hành vi giữa UIView.subviews và [NSView subviews]
NSArray* subViews = self.subviews;
for(UIView *aView in subViews) {
[aView removeFromSuperview];
}
Điều này làm việc tốt. Trong thực tế, tôi chưa bao giờ thực sự suy nghĩ nhiều cho đến khi tôi thử gần giống với một ứng dụng Mac OS X (từ một phân lớp NSView):
NSArray* subViews = [self subviews];
for(NSView *aView in subViews) {
[aView removeFromSuperview];
}
Điều đó hoàn toàn không hiệu quả. Cụ thể, tại thời gian chạy, tôi có được điều này:
*** Collection <NSCFArray: 0x1005208a0> was mutated while being enumerated.
tôi đã kết thúc làm việc đó như vậy:
NSArray* subViews = [[self subviews] copy];
for(NSView *aView in subViews) {
[aView removeFromSuperview];
}
[subViews release];
Đó là tốt. Điều gì khiến tôi lo lắng, đó là lý do tại sao nó hoạt động trên iPhone?
subviews là một tài sản bản sao:
@property(nonatomic,readonly,copy) NSArray *subviews;
Suy nghĩ đầu tiên của tôi đã, thu khí có lẽ @ synthesize'd trả về một bản sao khi thuộc tính bản sao được xác định. The doc là rõ ràng về ngữ nghĩa của bản sao cho người định cư, nhưng dường như không nói theo cách nào cho getters (hoặc ít nhất, điều đó không rõ ràng đối với tôi). Và thực tế, làm một vài thử nghiệm của riêng tôi, điều này rõ ràng dường như không phải là trường hợp. Điều đó tốt, tôi nghĩ việc trả lại một bản sao sẽ có vấn đề, vì một vài lý do.
Vì vậy, câu hỏi đặt ra là: mã trên hoạt động như thế nào trên iPhone? NSView rõ ràng đang trả về một con trỏ tới mảng phụ của thực tế, và có lẽ UIView thì không. Có lẽ nó chỉ đơn giản là một chi tiết triển khai của UIView và tôi không nên làm việc về nó.
Có ai có thể cung cấp thông tin chi tiết nào không?
Đó là chỉ một @ Mike lỗi. Nó chỉ là [someNSView subviews] trả về con trỏ tới mảng subviews, trong khi [someUIView subviews] trả về bản sao của mảng đó. Đây là lý do tại sao nó hoạt động tốt trên iOS. – jackal