@zaph có một giải pháp khá tốt. Tôi nghĩ tôi sẽ thử từ một góc độ khác. Vì mục tiêu-C là Mục tiêu -C, tại sao không xác định một số loại đối tượng để thực hiện vòng lặp theo thời gian này? Gợi ý: điều này tồn tại. Chúng ta có thể sử dụng NSTimer và thuộc tính userInfo của nó để làm việc này. Tôi nghĩ rằng các giải pháp là loại thanh lịch, nếu không phải là một khó chịu hack.
// Somewhere in code.... to start the 'loop'
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
action:@selector(processNextTransaction:)
userInfo:@{
@"gains": [gainsArray mutableCopy]
}
repeats:NO];
// What handles each 'iteration' of your 'loop'
- (void)processNextTransaction:(NSTimer *)loopTimer {
NSMutableArray *gains = [loopTimer.userInfo objectForKey:@"gains"];
if(gains && gains.count > 0) {
id transaction = [gains firstObject];
[gains removeObjectAtIndex:0]; // NSMutableArray should really return the object we're removing, but it doesn't...
[self private_addTransactionToBankroll:transaction];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
action:@selector(processNextTransaction:)
userInfo:@{
@"gains": gains
}
repeats:NO];
}
}
Tôi sẽ kiểm tra xem NSTimer có được giữ lại bằng cách được thêm vào vòng lặp chạy hay không. Nếu đó không phải là trường hợp, bạn nên lưu trữ một tham chiếu đến nó như là một tài sản trên bất cứ lớp nào đang quản lý tất cả điều này.
Cũng cần lưu ý rằng vì NSTimers được cài đặt trên vòng lặp chính theo mặc định, bạn không cần phải lo lắng về tất cả các công cụ GCD. Sau đó, một lần nữa, nếu công việc này là công việc khá khó khăn, bạn có thể muốn -processNextTransaction:
để giảm tải công việc của nó lên một hàng đợi GCD khác và sau đó trở lại hàng đợi chính để khởi tạo thể hiện NSTimer.
Đảm bảo sử dụng phương thức -scheduledTimer...
; timer...
phương pháp lớp học trên NSTimer
không cài đặt nó trên bất kỳ vòng lặp, và các đối tượng chỉ ngồi trong không gian làm gì. Đừng làm repeats:YES
, điều đó sẽ bi thảm, vì bạn muốn có bộ hẹn giờ gắn liền với vòng lặp chạy willy-nilly, không có tham chiếu nào trỏ đến chúng để biết cách hoặc nơi dừng chúng. Đây thường là một điều xấu.
Để tránh EXC_BAD_ACCESS
ngoại lệ, không bao giờ dealloc đối tượng có phương thức NSTimer
sẽ gọi, nếu bộ hẹn giờ đó chưa kích hoạt. Bạn có thể muốn lưu trữ NSTimer
đang chờ xử lý trong một thuộc tính trên lớp của bạn để bạn có thể xử lý loại điều này. Nếu đó là một ViewController mà là quản lý tất cả điều này (mà nó thường là), sau đó tôi sẽ sử dụng mã sau đây để làm sạch bộ đếm thời gian trên -viewWillDisappear
. (Điều này giả định rằng bạn đang thiết lập một bộ đếm thời gian mới cho một số @property
, self.timer
)
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if(self.timer) {
[self.timer invalidate]; // -invalidate removes it from the run loop.
self.timer = nil; // Stop pointing at it so ARC destroys it.
}
}
Sử dụng một 'NSTimer' cũng giải pháp tốt. – zaph
@zaph NSTimer không hoạt động tốt với cocos2d hoặc SpriteKit. Ưu tiên các phương thức 'schedule' được xây dựng cung cấp bởi CCNode và tất cả các lớp dẫn xuất của nó. – YvesLeBorg