6

Tôi có một vấn đề rất lạ với các công cụ rò rỉ bộ nhớ 4,3 Xcode ... Về cơ bản nó không hoạt động trong trường hợp sau đây ...rò rỉ vấn đề phát hiện trong iOS với Xcode 4.3

  1. Dự án được tạo ra mà không ARC ủng hộ.
  2. Tạo một lớp đơn giản mà được thừa hưởng UIView
  3. sử dụng một "nút" để tạo thể hiện của lớp này và "rò rỉ" nó ... rò rỉ sẽ không được đánh bắt bởi rò rỉ Instruments

vì vậy đây là mã của lớp có vấn đề

@interface LeakTestView : UIView 
- (id)initWithFrame:(CGRect)frame; 
@end 

@implementation LeakTestView 
- (id)initWithFrame:(CGRect)frame 
{ 
    NSLog(@"initWithFrame called"); 
    self = [super initWithFrame:frame]; 
    if (self) { 

     // Initialization code 
    } 
    return self; 
} 
@end 

Và bây giờ tôi tạo ra rò rỉ ...

- (IBAction)leak:(id)sender { 
    LeakTestView* leak=[[LeakTestView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)]; 
    NSLog(@"class is %@", [leak class]); 
} 

Vì vậy, vấn đề là bị rò rỉ này sẽ không được phát hiện ...

Nếu tôi thay đổi lớp cơ sở để NSObject và thay vì initWithFrame override init (xem dưới đây) thì bị rò rỉ sẽ được phát hiện ....

vì vậy đây là mã cho rò rỉ rằng sẼ được phát hiện

@interface LeakTestView : NSObject 
- (id) init; 
@end 


@implementation LeakTestView 

- (id) init { 
    NSLog(@"init called"); 
    self = [super init]; 
    if (self) { 

    } 
    return self; 
} 
@end 

Nếu tôi có thể tạo đối tượng bây giờ và rời khỏi nó - phát hiện rò rỉ sẽ kích hoạt và bị rò rỉ sẽ được "nhìn thấy" vào Instruments.

- (IBAction)leak:(id)sender { 
    LeakTestView* leak=[[LeakTestView alloc]init]; 
    NSLog(@"class is %@", [leak class]); 
} 

Bất kỳ ý tưởng gì đang xảy ra? Tại sao sự rò rỉ của lớp con UIView sẽ không được phát hiện nhưng việc thay đổi lớp cơ sở thành NSObject sẽ "khắc phục" vấn đề này? Oh và có đối tượng bị rò rỉ có thể được nhìn thấy bằng cách sử dụng "Dấu heap" - một dấu trước khi bị rò rỉ và một dấu sau khi tôi nhấp vào nút và tạo ra sự rò rỉ - lớp sẽ được nhìn thấy trong vùng đồng bằng heap ...

EDIT: thêm một "funny" tình hình ... Nếu tôi loại bỏ các "init" công cụ (chỉ alloc đối tượng)

LeakTestView* leak=[LeakTestView alloc]; 

sau đó rò rỉ sẽ được phát hiện không có vấn đề lớp cơ sở là gì ... gì địa ngục đang diễn ra ở đây?

EDIT2: một điều "hài hước" khác. Vấn đề phát hiện rò rỉ có thể được quan sát chỉ trong Simulator (iOS 5.0, 9A334 là của tôi) nhưng rò rỉ sẽ được phát hiện luôn nếu sử dụng thiết bị iPad ...

Mọi bình luận? Nếu bạn không có vấn đề hoặc xem xét rằng tôi speek "nằm" chỉ cho tôi biết tôi sai và trường hợp trên là làm việc "tốt" - rò rỉ tôi mô tả được phát hiện bởi các công cụ xCode của bạn!

+0

"Công cụ" là gì ?? Bạn đang sử dụng máy dò rò rỉ nào? –

Trả lời

0

Có thể nó không bị rò rỉ?

Bạn đang gọi phương thức là hộp đen. Cách UIView initWithFrame được triển khai không phải là doanh nghiệp của bạn. Nó có hợp đồng loại, nhưng bạn không có quyền yêu cầu điều này bị rò rỉ nữa, bạn có thể giả định số người giữ lại là 1.

Rò rỉ là công cụ hữu ích nhưng nó không làm những gì bạn nghĩ. Nó không cho bạn biết khi bạn đã sai lầm. Nó cho bạn biết khi bạn có phân bổ không thể truy cập. Đây không phải là điều tương tự.

Hoặc, đó có thể là lỗi.

+0

Cảm ơn câu trả lời. Tôi biết rằng Rò rỉ phát hiện phân bổ không thể truy cập (và công cụ này không phải là một "ma thuật" giải pháp để hiển thị nơi các vấn đề vào mã), nhưng nếu tôi kiểm tra số còn lại của đối tượng "bị rò rỉ" nó nói 1 (vì nó nên) do đó, chỉ giữ lại đó là "hoạt động" là từ phân bổ. Vì vậy, đối với tôi có một rò rỉ mà các dụng cụ không thể "tìm" ngay cả khi nó là "một trong những đơn giản như vậy". Nó thực sự dễ dàng để tạo ra một dự án mẫu để kiểm tra nó bằng cách tự của bạn - chỉ cần sử dụng các mô phỏng và rò rỉ một phân lớp của UIView, và kiểm tra các dụng cụ sẽ tìm thấy nó ... – Sunman

+0

Tôi biết, tôi hoàn toàn đồng ý nó là lạ, nhưng giữ lại số lượng thực sự, thực sự là nói cho bạn không có gì. Bỏ qua nó> http://www.friday.com/bbum/2011/12/18/retaincount-is-useless/ – hooleyhoop

+0

Tôi biết rằng số lượng giữ lại không thể được sử dụng để nói "có bao nhiêu đối tượng bên ngoài tham chiếu đến tôi" vì Việc thực hiện @property và có thể các yếu tố khác nhưng trong một số trường hợp nó cung cấp thông tin những gì đang xảy ra - và trong trường hợp trên nó bảo đảm rằng tham chiếu duy nhất đến đối tượng mới được tạo là từ cấp phát và initWithFrame không tăng số lượng lưu giữ và trong bằng cách này ngăn chặn các công cụ rò rỉ để tìm rò rỉ ... – Sunman

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