2011-12-07 33 views
12

Tôi đã tìm ra một vấn đề lớn với CADisplayLink.Làm cách nào để dừng và tiếp tục một CADisplayLink một cách chính xác?

Tôi có EAGLLayer cơ bản nhất với OpenGL ES 1.1 vẽ hình tam giác xoay để thử nghiệm. Điều này cần một phương pháp chạy vòng lặp được gọi với tốc độ làm tươi màn hình, vì vậy tôi bắt đầu runloop như thế này:

- (void)startRunloop { 
    if (!animating) { 
     CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)]; 
     [dl setFrameInterval:1.0]; 
     [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     self.displayLink = dl; 

     animating = YES; 
    } 
} 

- (void)stopRunloop { 
    if (animating) { 
     [self.displayLink invalidate]; 
     self.displayLink = nil; 
     animating = NO; 
    } 
} 

Khi thử nghiệm ứng dụng ra mắt, tôi gọi -startRunloop. Khi tôi nhấn vào màn hình, tôi gọi -stopRunloop. Khi tôi nhấn lần nữa, tôi gọi -startRunloop. Và kể từ đó trở đi. Bóng bàn.

Tôi đang đo tần suất phương thức -drawFrame được gọi trong 20 giây và NSLog nó.

  • Vòng bắt đầu/dừng đầu tiên luôn hoạt động ở mức 100%. Tôi nhận được tốc độ khung hình tối đa.

  • Tất cả các chu kỳ bắt đầu/dừng SUBSEQUENT chỉ hiển thị khoảng 80% hiệu suất. Tôi nhận được tốc độ khung hình nhỏ hơn đáng kể. Nhưng: Luôn gần như giống hệt nhau, +/- 2 khung hình. Không có xu hướng làm suy giảm hơn nữa ngay cả sau 50 chu kỳ khởi động/dừng.

Tóm lại: Tạo một CADisplayLink như tôi làm ở trên là tốt, cho đến khi nó hết hiệu lực hoặc tạm dừng. Sau đó, bất kỳ CADisplayLink mới nào không hoạt động tốt nữa. Ngay cả khi nó được tạo mới và theo cùng một cách như trước. Điều này cũng đúng nếu tôi tạm dừng/tiếp tục nó bằng cách gọi phương thức -setPaused: với YES/NO.

Tôi đã đảm bảo với Allocations và VM Tracker Instruments rằng không có vấn đề về quản lý bộ nhớ. Tôi cũng đã kiểm tra rằng phương thức -valvalate của CADisplayLink thực sự được gọi.

iOS 4.0 trên thiết bị (iPhone 4).

Tại sao lại như vậy? Tui bỏ lỡ điều gì vậy?

+0

Nghe có vẻ như một lỗi. Tôi nghĩ bạn cần phải gửi báo cáo lỗi cho Apple. –

+0

Tôi có cùng một vấn đề. Tôi không cần DisplayLink chạy mọi lúc, nhưng có vẻ như tôi không có lựa chọn nào. Vì vậy, bây giờ tôi chỉ sử dụng cờ trong bộ chọn xử lý thay vì sử dụng isPaused. –

Trả lời

1

Bạn tạo một thể hiện liên kết hiển thị mới với mọi cuộc gọi bắt đầu. Bạn đã thử sử dụng lại cùng một trường hợp chưa?

Ngoài ra, bạn luôn có thể tạm dừng liên kết hiển thị.

5

Tôi đang sử dụng

[displayLink removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

xem nếu nó làm việc cho bạn

5

Tôi nghĩ rằng bạn biết những gì bạn thực sự muốn chỉ đơn giản là để tạm dừng và bỏ tạm dừng liên kết hiển thị của bạn.

- (void)createRunloop { 
    CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:@selector(drawFrame)]; 
    [dl setFrameInterval:1.0]; 
    [dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    self.displayLink = dl; 
    // start in running state, your choice. 
    dl.paused = NO; 
} 
- (void)startRunloop { 
    self.displayLink.paused = NO; 
} 
- (void)stopRunloop { 
    self.displayLink.paused = YES; 
} 
- (void)destroyRunloop { 
     [self.displayLink invalidate]; 
     self.displayLink = nil; 
} 
0

Hãy thử điều này trong Swift,

displayLink?.remove(from: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode) 
Các vấn đề liên quan