Tôi mới sử dụng ARC nhưng hiểu cách hoạt động và tôi đang dùng thử. Tôi đang trên iOS nên bộ nhớ là một mối quan tâm nghiêm trọng.Cách buộc phát hành trên iOS
Tôi có lớp MyObject chứa nhiều dữ liệu lớn. Tôi muốn phát hành nó và tải một bộ dữ liệu mới.
MyObject *object;
object = [[MyObject alloc] initWithData:folder1]; // load data from folder1
// later...
object = [[MyObject alloc] initWithData:folder2]; // load data from folder2
Điều này làm việc tốt mà không bị rò rỉ, và tôi đoán ARC chèn [phát hành đối tượng] trước bài tập mới. Vấn đề của tôi là dữ liệu bên trong 'đối tượng' được phát hành sau khi bộ mới được cấp phát và tôi hết bộ nhớ. Điều tôi thực sự muốn có thể làm là:
object = nil;
<function to pop the pool, wait till everything is deallocated>
object = [MyObject alloc] initWithData:folder2]; // load data from folder2
nhưng tôi không chắc chắn cách thực hiện điều đó. Tôi có thể chạy phân bổ mới trên một performselector afterdelay, nhưng nó cảm thấy như tôi đang chụp trong bóng tối và một chút hack. Có thể là cách thích hợp để thực hiện việc này?
PS Tôi đã thử tìm kiếm câu trả lời, nhưng tất cả kết quả là về rò rỉ bộ nhớ và cách đảm bảo các biến nằm ngoài phạm vi và đặt biến thành nil, v.v. điều thời gian.
CẬP NHẬT
Cảm ơn câu trả lời, tôi đã muốn thử
object = nil;
object = [MyObject alloc] initWithData:folder2];
và nó đã không làm việc. Tôi không chắc liệu nó có được cho là có hay không. Bây giờ tôi hiểu rằng nó là phải làm việc, nhưng tôi phải có một cái gì đó khác giữ cho nó cho rằng phần của một giây. Tôi có NSLogs trong tất cả các phương thức init/dealloc của tôi, và tôi có thể thấy đầu tiên tất cả các trường hợp của các lớp mới (của các thanh ngang của MyObject) được gọi, và sau đó gần như ngay sau (trong vài ms), dealloc của MyObject , tiếp theo là deallocs của các ivars của nó. Tôi cũng đã thử @autorelease nhưng điều tương tự cũng xảy ra.
Tôi đã tìm kiếm trong suốt dự án và dán tất cả mã mà tôi nghĩ có thể có liên quan đến điều này.
@interface AppDelegate : UIResponder <UIApplicationDelegate>;
@property PBSoundSession *soundSession;
@end
//--------------------------------------------------------------
@implementation AppDelegate
// onTimer fired at 60Hz
-(void)onTimer:(NSTimer *) theTimer {
[oscReceiver readIncoming]; // check incoming OSC messages
// then do a bunch of stuff with _soundSession;
}
@end
//--------------------------------------------------------------
@implementation OscReceiver
-(void)readIncoming {
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
// parse all incoming messages
if(bLoadNewSoundBank) {
NSString *newFolder = parseNewFolder();
appDelegate.soundSession = nil;
appDelegate.soundSession = [MyObject alloc] initWithData:newFolder];
}
}
@end
//--------------------------------------------------------------
@implementation GuiController
// onTimer fired at 10Hz
-(void)onTimer:(NSTimer *) theTimer {
PBSoundSession *soundSession = appDelegate.soundSession;
// update gui with received values
}
@end
tôi nghĩ nó có thể là biến cục bộ 'soundSession' trong GuiController :: OnTimer giữ vào appDelegate.soundSession cũ trong suốt thời gian của phương pháp đó, nhưng tôi ngạc nhiên cho ý kiến ra tất cả các mã GUI (trong thực tế vô hiệu hóa bộ đếm thời gian), không có sự khác biệt.
Có cách nào để tìm ra tại thời điểm đó, người vẫn đang nắm giữ ứng dụng của tôiDelegate.soundSession không? Tôi đặt một điểm dừng nơi tôi đặt nó thành không, nhưng không thể tìm thấy bất kỳ thông tin hữu ích nào. Tôi đã thử mẫu Thiết bị phân bổ dụng cụ, nhưng không thể tìm thấy bất kỳ thứ gì hữu ích ở đó (có lẽ vì tôi không biết phải tìm đâu).
Đây là những gì phân bổ theo dõi của tôi trông giống như, bạn có thể thấy bộ nhớ là tất cả deallocated một chút quá muộn! .
Vâng, bạn sẽ nhận được nhiều thứ bạn muốn bằng cách chỉ cần thực hiện 'object = nil;' trước khi bạn cấp phát/init đối tượng mới. –