2009-10-07 27 views
26

Bạn có phải phát hành IBOulets trong dealloc không? Tôi không chắc chắn về điều này bởi vì tôi đã không làm phân bổ và thường bạn chỉ phát hành cho một cái gì đó bạn gọi là cấp phát trên. Có ai biết không?Bạn có phải phát hành IBOulets trong dealloc không?

+0

Nhân bản: http://stackoverflow.com/questions/61838/do-i-need-to-release-xib-resources – Casebash

Trả lời

35

IBOutlets của bạn có thể là @properties. Nếu họ đang có, và bạn có retain như một thuộc tính, sau đó bạn cần để phát hành trong -dealloc

Nói cách khác:

@interface MyViewController : UIViewController { 
    IBOutlet UITableView *myTable; 
} 

@property (nonatomic, retain) IBOutlet UITableView *myTable; 

@end 

Bạn sẽ phải [myTable release]; trong dealloc của bạn.

Nếu bạn thực hiện một Navigation mới dựa trên App trong Xcode, và nhìn vào appdelegate.h:

@interface Untitled1AppDelegate : NSObject <UIApplicationDelegate> { 

    UIWindow *window; 
    UINavigationController *navigationController; 
} 

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController; 

@end 

và dealloc cho appdelegate.m:

- (void)dealloc { 
    [navigationController release]; 
    [window release]; 
    [super dealloc]; 
} 

Điều quan trọng để xem dưới đây là các dòng như sau:

@property (nonatomic, retain) IBOutlet UIWindow *window; 

Nếu có giữ lại trong đó, điều đó có nghĩa là tài sản đang được " sở hữu "bởi mã của bạn và bạn phải phát hành nó.

Tất nhiên, có những cách khác, chẳng hạn như không khai báo IBOutlets làm thuộc tính hoặc khai báo chúng dưới dạng thuộc tính mà không giữ lại. Tôi thấy rằng trong hầu hết các trường hợp, tôi muốn có chúng được giữ lại tài sản, mà sau đó tôi phải phát hành một cách rõ ràng. Một ví dụ về điều này là khi bạn lật từ bộ điều khiển xem này sang bộ điều khiển khác. Khi một bộ điều khiển xem bị loại bỏ, các chế độ xem của nó bị loại bỏ và chúng được giải phóng. Bất kỳ IBOutlet UILabels trên khung nhìn đó cũng sẽ được giải phóng nếu tôi không giữ chúng lại. Điều đó có nghĩa là khi tôi quay trở lại chế độ xem cũ, tôi phải đi qua và đặt lại nhãn và điều khiển của mình thành giá trị cuối cùng, khi tôi có thể dễ dàng lưu chúng nếu tôi chỉ giữ lại IBOutlet.

2

Như bạn đã nói, bạn nên giải phóng mọi thứ mà bạn tự phân bổ (với alloc hoặc copy). Nó hoạt động theo cách khác: bạn không nên phát hành bất kỳ đối tượng Cocoa nào bạn không phân bổ chính mình (một số hàm CoreFoundation phân bổ và bạn chịu trách nhiệm giải phóng chúng, nhưng nó không phải là trường hợp ở đây).

Nếu bạn không phân bổ IBOutlet, bạn không phải giải phóng nó, trừ khi tất nhiên, vì lý do nào đó, bạn giữ lại nó ở đâu đó.

+1

Cụm từ khóa là ("trừ khi .. bạn đặt lại nó ở đâu đó") sẽ xảy ra nếu bạn sử dụng làm một tài sản (nonatomic, giữ lại). – Fraggle

8

Nó không phải về IBOutlet, đó là về tuyên bố của bạn. Nếu bạn sử dụng trình hướng dẫn dự án mới trong Xcode, bạn có thể nhận được một số mã như thế này trong tệp tiêu đề của bạn.

@property (nonatomic, retain) IBOutlet UIWindow *window; 
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController; 

Bạn có thể thấy, có giữ lại từ khóa trong tệp tiêu đề. Theo hướng dẫn quản lý bộ nhớ, bạn PHẢI phát hành mọi thứ bạn giữ lại (bằng cách gọi cấp phát, sao chép, giữ lại, v.v.). Và bạn có giữ lại trong mã của mình thì bạn phải phát hành nó.

Ngoài ra, trình hướng dẫn đã thêm một số mã phát hành cho bạn.

- (void)dealloc { 
    [tabBarController release]; 
    [window release]; 
    [super dealloc]; 
} 
9

Nếu bạn chỉ sử dụng IBOutlet trong giao diện của mình, bạn KHÔNG cần phải giải phóng chúng. Lý do là trừ khi bạn giữ lại chúng một cách rõ ràng trong mã của bạn, chúng chỉ đang được thiết lập. Họ dính xung quanh vì quan điểm là có. Rõ ràng, nếu bạn cũng sử dụng các thuộc tính và giữ lại chúng, bạn cần phải phát hành trên dealloc.

+0

Câu trả lời này không xung đột với câu hỏi trên? Bạn có cần hay không? Thật bôi rôi. – erotsppa

+0

Không, nó không xung đột: "Rõ ràng, nếu bạn cũng sử dụng các thuộc tính và giữ lại chúng, bạn cần phải phát hành trên dealloc". – mahboudz

+0

Là một thử nghiệm, hãy tạo một ứng dụng Nav Based mới trong Xcode. Bạn sẽ thấy cách họ phát hành IBOutlets trong dealloc của họ. – mahboudz

1

Dưới đây là những gì tôi đã và đang làm đối với IBOutlet đối tượng (kết hợp với một tập tin NIB) với:

@interface MyViewController : UIViewController { 
    UILabel *label; 
} 

@property (nonatomic, retain) IBOutlet UILabel *label; 

@end 

@implementation MyViewController 
@synthesize label; 

- (void)setView:(UIView *)aView { 
    if (!aView) { 
    // view is being set to nil 
    // set outlets to nil to get the benefit of the didReceiveMemoryWarning! 
    self.label = nil; 
    } 
    // Invoke super's implementation last 
    [super setView:aView]; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
} 

- (void)viewDidUnload { 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
    self.label = nil; 
} 

- (void)didReceiveMemoryWarning { 
    // Releases the view if it doesn't have a superview. 
    [super didReceiveMemoryWarning]; 

    // Release any cached data, images, etc that aren't in use. 
} 

- (void)dealloc { 
    [label release]; 
    [super dealloc]; 
} 

Side câu hỏi: Liệu nó có ý nghĩa hơn để sử dụng self.label = nil trong dealloc, hoặc phải release được một cách rõ ràng được gọi là (ví dụ, để giữ cho máy phân tích tĩnh hạnh phúc)?

Tôi cho rằng, tại thời điểm đó, chúng tôi vẫn đang trên đường thoát, vì vậy không cần thiết lập các đối tượng IBOutlet của chúng tôi thành không.

1

Nếu đây là BlahViewController.h của bạn:

// BlahViewController.h 
#import <UIKit/UIKit.h> 
@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
} 
@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar; 

@end 

Sau đó, đây sẽ là dealloc của bạn trong BlahViewController.m:

- (void)dealloc 
{ 
    [navigationBar release]; 
    [super dealloc]; 
} 

Tuy nhiên, nếu đây là BlahViewController.h của bạn:

// BlahViewController.h 
#import <UIKit/UIKit.h> 
@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
} 

@end 

Sau đó, đây sẽ là dealloc trong BlahViewC của bạn ontroller.m:

- (void)dealloc 
{ 
    [super dealloc]; 
} 

Và cuối cùng, nếu đây là BlahViewController.h của bạn:

// BlahViewController.h 
#import <UIKit/UIKit.h> 

@interface BlahViewController 
{ 
    IBOutlet UINavigationBar *navigationBar; 
    IBOutlet MKMapView *map; 
} 

@property (nonatomic, retain) IBOutlet UINavigationBar *navigationBar; 

@end 

Sau đó, điều này sẽ là của bạn dealloc trong BlahViewController.m:

- (void)dealloc 
{ 
    [navigationBar release]; 
    [super dealloc]; 
} 

Nói tóm lại, nếu bạn khai báo nó là tài sản, với retain, thì bạn cần phải giải phóng nó.

2

Để trả lời câu hỏi phụ của Joe D'Andrea. Bạn có thể sử dụng self.label = nil;. Bởi vì nó được gọi setLabel, được tự động tạo:

- (void)setLabel:(UILabel *)input 
{ 
    [label autorelease]; 
    label = [input retain]; 
} 

Như bạn có thể thấy hiện nay label sẽ được phát hành sau đó nil được gán cho nhãn hiệu này.

Nhưng hãy đảm bảo bạn không viết nó là label = nil. Rằng sẽ không làm việc. Vì bạn cần phải gọi phương thức truy nhập nhãn được tạo tự động.

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