2009-05-30 17 views
5

Tôi gọi một phương thức mà đi trong một thread nền:Tại sao không có hồ bơi autorelease khi tôi thực hiệnSelectorInBackground :?

[self performSelectorInBackground:@selector(loadViewControllerWithIndex:) withObject:[NSNumber numberWithInt:viewControllerIndex]]; 

sau đó, tôi có thực hiện phương pháp này mà được gọi bởi bộ chọn:

- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj { 
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init]; 
    NSInteger vcIndex = [indexNumberObj intValue]; 

    Class c; 
    UIViewController *controller = [viewControllers objectAtIndex:vcIndex]; 

    switch (vcIndex) { 
     case 0: 
      c = [MyFirstViewController class]; 
      break; 
     case 1: 
      c = [MySecondViewController class]; 
      break; 
     default: 
      NSLog(@"unknown index for loading view controller: %d", vcIndex); // error 
      break; 
    } 

    if ((NSNull *)controller == [NSNull null]) { 
     controller = [[c alloc] initWithNib]; 
     [viewControllers replaceObjectAtIndex:vcIndex withObject:controller]; 
     [controller release]; 
    } 

    if (controller.view.superview == nil) { 
     UIView *placeholderView = [viewControllerPlaceholderViews objectAtIndex:vcIndex]; 
     [placeholderView addSubview:controller.view]; 
    } 

    [arPool release]; 
} 

Althoug tôi làm tạo ra một hồ bơi autorelease có cho chủ đề đó, tôi luôn gặp phải lỗi này:

2009-05-30 12:03:09.910 Demo[1827:3f03] *** _NSAutoreleaseNoPool(): Object 0x523e50 of class NSCFNumber autoreleased with no pool in place - just leaking 
Stack: (0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012) 

Nếu tôi lấy đi nhóm tự động, tôi nhận được toàn bộ các thư như thế này. Tôi cũng đã cố gắng để tạo ra một hồ bơi autorelease xung quanh cuộc gọi của performSelectorInBackground :, nhưng điều đó không giúp đỡ.

Tôi nghi ngờ tham số, nhưng tôi không biết tại sao trình biên dịch lại phàn nàn về một NSCFNumber. Tui bỏ lỡ điều gì vậy?

Biến mẫu của tôi là tất cả "nonatomic". Đó có thể là một vấn đề?

CẬP NHẬT: Tôi cũng có thể nghi ngờ rằng một số biến đã được thêm vào một nhóm autorelease của chủ đề chính (có thể là một ivar), và bây giờ nó trys để phát hành một bên trong hồ bơi autorelease sai? Nếu vậy, làm thế nào tôi có thể khắc phục điều đó? (chết tiệt, thứ này rất phức tạp;))

+0

Hãy thử đặt một breakpoint trên _NSAutoreleaseNoPool để xem nơi nó đang được gọi từ – rpetrich

+0

Câu hỏi tiếp tuyến: ở đây một bộ điều khiển mới, được cấp phát cục bộ trong chuỗi này, được thêm vào một mảng toàn cục và chế độ xem của nó được thêm dưới dạng một chế độ xem phụ. Đây có phải là vấn đề trong đó đối tượng được tạo trong một nhóm khác với vùng chứa của nó không? –

+0

@dk bạn không nên đặt câu hỏi tiếp tuyến, hãy đặt câu hỏi riêng! Dù sao tôi khuyên mạnh mẽ chống lại việc tạo ra các đối tượng liên quan đến giao diện người dùng (bộ điều khiển và quan điểm) trong một chủ đề không chính. Đó là một thảm họa đang chờ xảy ra. – Yuji

Trả lời

6

Rất có thể lý do là vì đối tượng bị rò rỉ (một NSNumber), là một tham số được truyền từ bên ngoài luồng. Do đó, biến này thuộc về chuỗi gọi (và hồ bơi tự động của nó)

Lý do mà nhóm tự động trả lời xung quanh cuộc gọi luồng không hoạt động, là do trình tạo luồng (performSelectorInbackground) - trả về ngay lập tức, rất có thể trong khi luồng vẫn đang chạy.

Tôi đề nghị bạn thực hiện một bản phát hành trên thông số của bộ chọn của bạn sau khi chuyển nó làm đối số.

+1

Có, chuyển các đối tượng được tự động phát hành thành các chuỗi mới có thể gây ra hành vi rất lạ. –

2

Tôi đồng ý rằng rất có thể lý do cho điều này là do đối tượng bị rò rỉ (một NSNumber), là một tham số được truyền từ bên ngoài luồng. Do đó, biến này thuộc về tiểu trình đang gọi (và hồ bơi autorelease của nó)

Các thread gọi nên sử dụng NSAutoreleasePool và tôi đề nghị bạn nên thêm một hướng dẫn giữ lại để tham số của bạn như:

- (void) loadViewControllerWithIndex:(NSNumber *)indexNumberObj { 
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init]; 
    [indexNumberObj retain]; 

    .... 

    [arPool release]; 
    } 
Các vấn đề liên quan