मैं एक स्वास्थ्य बार लागू कर रहा हूं जो उपयोगकर्ता इनपुट के माध्यम से एनिमेट करता है।एक लॉक निष्पादित करने के लिए जो एक एनीमेशन पूर्ण होने तक प्रतीक्षा करता है?
ये एनिमेशन इसे एक निश्चित राशि (50 इकाइयों कहते हैं) द्वारा ऊपर या नीचे जाते हैं और बटन प्रेस का परिणाम होते हैं। दो बटन हैं बढ़ना और घटना।
मैं स्वास्थ्य बार पर एक ताला निष्पादित करना चाहता हूं ताकि एक ही समय में केवल एक धागा इसे बदल सके। समस्या यह है कि मुझे डेडलॉक मिल रहा है।
मैं अनुमान लगा रहा हूं क्योंकि एक अलग थ्रेड एक थ्रेड चलाता है जो किसी अन्य थ्रेड द्वारा आयोजित किया जाता है। लेकिन जब एनीमेशन पूरा हो जाता है तो वह ताला रास्ता देगा। [UIView AnimateWithDuration] पूर्ण होने पर आप लॉक को कैसे कार्यान्वित करते हैं?
मुझे आश्चर्य है कि NSConditionLock
जाने का तरीका है, लेकिन अगर मैं अनावश्यक जटिलता से बचने के लिए संभव हो तो NSLocks का उपयोग करना चाहता हूं। आप क्या सलाह देते हैं?
(अंततः मैं एनिमेशन "ऊपर क़तार" जबकि उपयोगकर्ता इनपुट जारी रखने के लिए दे करना चाहते हैं, लेकिन अब मैं सिर्फ काम कर ताला पाने के लिए, पहले चाहते हैं तो भी यह ब्लॉक इनपुट।)
(हम्म के लिए आते हैं इसके बारे में सोचें, एक ही UIView के लिए एक समय में केवल एक [UIView AnimateWithDuration] चल रहा है। एक दूसरी कॉल पहले को बाधित करेगी, जिससे पूरा करने वाला हैंडलर पहले के लिए तुरंत चल रहा है। हो सकता है कि पहले लॉक पहले मौका हो अनलॉक करने के लिए। इस मामले में लॉकिंग को संभालने का सबसे अच्छा तरीका क्या है? शायद मुझे ग्रैंड सेंट्रल डिस्पैच पर फिर से जाना चाहिए, लेकिन मैं देखना चाहता था कि कोई आसान तरीका है या नहीं।)
ViewController.h में घोषित करता है:
NSLock *_lock;
ViewController.m में मेरे पास है:
loadView में:
_lock = [[NSLock alloc] init];
ViewController.m के बाकी (प्रासंगिक भागों):
-(void)tryTheLockWithStr:(NSString *)str
{
LLog(@"\n");
LLog(@" tryTheLock %@..", str);
if ([_lock tryLock] == NO)
{
NSLog(@"LOCKED.");
}
else
{
NSLog(@"free.");
[_lock unlock];
}
}
// TOUCH DECREASE BUTTON
-(void)touchThreadButton1
{
LLog(@" touchThreadButton1..");
[self tryTheLockWithStr:@"beforeLock"];
[_lock lock];
[self tryTheLockWithStr:@"afterLock"];
int changeAmtInt = ((-1) * FILLBAR_CHANGE_AMT);
[self updateFillBar1Value:changeAmtInt];
[UIView animateWithDuration:1.0
delay:0.0
options:(UIViewAnimationOptionTransitionNone|UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionAllowUserInteraction)
animations:
^{
LLog(@" BEGIN animationBlock - val: %d", self.fillBar1Value)
self.fillBar1.frame = CGRectMake(FILLBAR_1_X_ORIGIN,FILLBAR_1_Y_ORIGIN, self.fillBar1Value,30);
}
completion:^(BOOL finished)
{
LLog(@" END animationBlock - val: %d - finished: %@", self.fillBar1Value, (finished ? @"YES" : @"NO"));
[self tryTheLockWithStr:@"beforeUnlock"];
[_lock unlock];
[self tryTheLockWithStr:@"afterUnlock"];
}
];
}
-(void)updateFillBar1Value:(int)changeAmt
{
self.prevFillBar1Value = self.fillBar1Value;
self.fillBar1Value += changeAmt;
if (self.fillBar1Value < FILLBAR_MIN_VALUE)
{
self.fillBar1Value = FILLBAR_MIN_VALUE;
}
else if (self.fillBar1Value > FILLBAR_MAX_VALUE)
{
self.fillBar1Value = FILLBAR_MAX_VALUE;
}
}
आउटपुट:
करने के लिए पुन निर्देश: टैप करें "कम करें" एक बार
touchThreadButton1 ..
tryTheLock beforeLock .. मुक्त।
tryTheLock afterLock .. लॉक किया गया। शुरू animationBlock - वैल: 250 अंत animationBlock - वैल: 250 - समाप्त: हाँ
tryTheLock beforeUnlock .. बंद कर दिया।
tryTheLock के बाद अनलॉक .. मुफ्त।
निष्कर्ष: यह अपेक्षा के अनुसार काम करता है।
-
आउटपुट:
निर्देश करने के लिए पुन: टैप करें "कम करें" तेज़ी से दो बार (प्रारंभिक एनीमेशन दखल) ..
touchThreadButton1 ..
tryTheLock पहले लॉक .. मुफ्त।
tryTheLock afterLock .. लॉक किया गया। .. 250 touchThreadButton1
tryTheLock beforeLock .. LOCKED: वैल - animationBlock शुरू करते हैं। * - [एनएसएलॉक लॉक]: डेडलॉक ('(शून्य)') * डीबग करने के लिए _NSLockError() पर तोड़ें।
निष्कर्ष। डेडलॉक त्रुटि। उपयोगकर्ता इनपुट जमे हुए है।
धन्यवाद श्रीमान! मैं सराहना करता हूं कि आप स्पष्ट रूप से NSOperationQueue का प्रदर्शन कैसे करते हैं। आकार की ऑपरेशन को अपनी कक्षा में Encapsulating बल्कि सुरुचिपूर्ण है। यह पूरी तरह से काम करता है। –
@ ब्लैकऑर्किड एफवाईआई, मुझे यकीन है कि इस सवाल से पहले आप लंबे समय से चले गए हैं, लेकिन मैंने इसे नाटकीय रूप से सरल दृष्टिकोण के साथ अपडेट किया है। – Rob
इच्छा है कि मैं इसे एक से अधिक बार बढ़ा सकता हूं। :) –