2012-03-29 25 views
27

Trong ios5.0 với ARC, trong rootviewcontroller của tôi, tôi gọi một phương thức trong một đối tượng quản lý bảo mật được tổ chức bởi ứng dụng ủy nhiệm. Trong phương pháp đó, tôi thiết lập bộ hẹn giờ như dưới đâyNSTimer không kích hoạt bộ chọn

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self 
             selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 

Tuy nhiên, điều này không bao giờ kích hoạt công cụ chọn. updateModel: không bao giờ được gọi. Điều gì có thể sai? Có một cách hiệu quả hơn tôi có thể làm điều này mà không cần sử dụng NStimer?

Trả lời

10

Bạn dường như hơi bị lẫn lộn với biến hẹn giờ của mình.

Bạn khởi tạo bộ tính giờ mới nhưng thực tế bạn chưa sử dụng. Bạn có muốn sử dụng bộ hẹn giờ bạn đã khởi tạo hoặc bạn muốn bạn ApplicationDelegate.timer không?

Dưới đây là hai giải pháp khả thi.

Lựa chọn One (giả định rằng bạn có một trường hợp lớp có tựa đề ApplicationDelegate và rằng nó có một tài sản timer):

ApplicationDelegate.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

Lựa chọn hai:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(updateModel:) userInfo:str repeats:YES]; 
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes]; 
+0

xin lỗi ab ra khỏi sai lầm trong bài viết .. Tôi đã chỉnh sửa nó để phản ánh cách tôi đang làm nó. Tôi đang sử dụng cách thứ hai bạn đề cập ... Nó vẫn không hoạt động. – inforeqd

+20

Cách thứ hai không chính xác. Nó đang cố gắng thêm bộ hẹn giờ hai lần. 'scheduleTimerWithTimeInterval: ...' đã thêm bộ hẹn giờ. Hãy chắc chắn rằng bạn đang chạy điều này trên các chủ đề chính. –

+0

có cách nào để tìm hiểu xem chuỗi thời gian nào đang được thêm vào? Tôi nghĩ rằng đó là chủ đề chính mà tôi đang thêm nó vào ... – inforeqd

5

dòng này có một số vấn đề:

[[NSRunLoop currentRunLoop] addTimer:ApplicationDelegate.timer forMode:NSRunLoopCommonModes]; 

Đầu tiên, không cần thiết. -scheduledTimerWithTimeInterval:... đã thêm bộ hẹn giờ vào runloop. Bạn không cần thêm lại.

Thứ hai, biến cục bộ timer không liên quan đến thuộc tính ApplicationDelegate.timer (có lẽ là nil vào thời điểm này).

Nếu bạn đang nói chuyện với đại biểu ứng dụng quá nhiều đến mức bạn đã tạo một cái gì đó gọi là ApplicationDelegate (toàn cầu? Macro?), Bạn đang nói chuyện với nó quá nhiều. Ứng dụng đại biểu là đại biểu cho ứng dụng; nó hỗ trợ trong ứng dụng bắt đầu và dừng và trả lời các sự kiện hệ thống. Ứng dụng đại biểu không phải là nơi để lưu trữ các biến toàn cầu. Một bộ đếm thời gian chắc chắn không phải là thứ bạn muốn lấy từ một đối tượng khác trong mọi trường hợp.

+0

xin lỗi về những sai lầm trong bài viết .. Tôi đã chỉnh sửa nó để phản ánh cách tôi đang làm nó .... Nó vẫn không hoạt động. Giới thiệu về nhận xét của bạn về cách sử dụng ứng dụng đại biểu .. Tôi có một mô hình mà tôi tạo ra sau khi phân tích cú pháp một phản ứng dịch vụ web. Tôi phải giữ lại mô hình cho tất cả các khung nhìn trong ứng dụng. Do đó, tôi nghĩ rằng mô hình nên được tổ chức bởi ứng dụng đại biểu khác, tôi không chắc chắn nơi nào khác tôi có thể giữ nó cho tất cả các quan điểm để sử dụng. – inforeqd

+1

Bạn có thể truyền mô hình cho các bộ điều khiển xem khi bạn xây dựng chúng, hoặc bạn có thể đặt các đối tượng mô hình của bạn trong một singleton. Bạn không nên treo chúng trên ứng dụng đại biểu. Điều này làm cho việc tái sử dụng mã trở nên rất khó khăn và làm phức tạp ứng dụng đại biểu (có chức năng riêng của nó để thực hiện không liên quan đến việc lưu trữ dữ liệu). –

8

tôi bắt cùng một vấn đề và tôi bắn timer đợi chính để giải quyết nó:

[NSURLConnection sendAsynchronousRequest:request queue:_operationQueue 
    completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){ 
     [self loopUpUpdateStart]; 
}]; 

-(void)loopUpUpdateStart{ 
    dispatch_async(dispatch_get_main_queue(), ^{ 

     _loopTimerForUpRevision = 
      NSTimer scheduledTimerWithTimeInterval: kNetworkLoopIntervalUpRev 
              target: self 
             selector: @selector(myCoolMethod) 
             userInfo: nil 
             repeats: YES]; 
     TRACE(@"Start Up updates"); 
    }); 
} 
105

cũng có thể là một vấn đề luồng:

nếu

[NSThread isMainThread] 

là sai sau đó bắt đầu bộ hẹn giờ như sau:

dispatch_async(dispatch_get_main_queue(), ^{ 
     timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick:) userInfo:nil repeats:YES]; 
    }) 
+0

+1, Cảm ơn bạn ... điều này đã làm các trick! – Joe

+1

Cảm ơn! Bạn có thể giải thích vấn đề luồng là gì không? – JohnH

+4

Bộ hẹn giờ chỉ thực hiện trong luồng chính (Giao diện người dùng) chính xác. Nếu bạn cố gắng khởi động bộ hẹn giờ trong một chủ đề khác với chủ đề chính nó sẽ không kích hoạt. – tmanthey

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