سؤال

هذا السؤال لديه بالفعل إجابة هنا:

غالبًا ما أرغب في تنفيذ بعض التعليمات البرمجية بضع microseconds في المستقبل. الآن ، أحلها مثل هذا:

- (void)someMethod
{
    // some code
}

وهذا:

[self performSelector:@selector(someMethod) withObject:nil afterDelay:0.1];

إنه يعمل ، لكن عليّ إنشاء طريقة جديدة في كل مرة. هل من الممكن استخدام الكتل بدلاً من هذا؟ في الأساس ، أبحث عن طريقة مثل:

[self performBlock:^{
    // some code
} afterDelay:0.1];

سيكون ذلك مفيدًا حقًا بالنسبة لي.

هل كانت مفيدة؟

المحلول

لا توجد طريقة مدمجة للقيام بذلك ، لكن ليس من السيء للغاية إضافتها عبر فئة:

@implementation NSObject (PerformBlockAfterDelay)

- (void)performBlock:(void (^)(void))block 
          afterDelay:(NSTimeInterval)delay 
{
    block = [[block copy] autorelease];
    [self performSelector:@selector(fireBlockAfterDelay:) 
               withObject:block 
               afterDelay:delay];
}

- (void)fireBlockAfterDelay:(void (^)(void))block {
    block();
}

@end

الائتمان ل مايك آش للتنفيذ الأساسي.

نصائح أخرى

إليك تقنية بسيطة ، استنادًا إلى GCD ، التي أستخدمها:

void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay),
      dispatch_get_current_queue(), block);
}

أنا لست خبيرًا في GCD ، وسأكون مهتمًا بالتعليقات على هذا الحل.

هناك طريقة أخرى (ربما أسوأ طريقة للقيام بذلك لأسباب عديدة) هي:

[UIView animateWithDuration:0.0 delay:5.0 options:UIViewAnimationOptionAllowUserInteraction animations:^{
} completion:^(BOOL finished) {
    //do stuff here
}];

إذا كنت بحاجة إلى تأخير أطول على وجه التحديد ، فإن الحلول أعلاه تعمل على ما يرام. لقد استخدمت نهج نيك مع نجاح كبير.

ومع ذلك ، إذا كنت تريد فقط تشغيل الكتلة الخاصة بك أثناء التكرار التالي للحلقة الرئيسية ، فيمكنك تقليمها إلى أبعد من ذلك مع ما يلي فقط:

[[NSOperationQueue mainQueue] addOperationWithBlock:aBlock];

هذا أقرب إلى استخدام الأداء: مع Afterdelay من 0.0F

لقد استخدمت رمزًا مشابهًا مثل هذا:

double delayInSeconds = 0.2f;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
      //whatever you wanted to do here...  
    });

هناك فئة لطيفة وكاملة تتولى هذا الموقف هنا:

https://gist.github.com/955123

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top