// The MIT License (MIT) // // Copyright (c) 2015 ( https://github.com/callmewhy ) // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #import "HWWeakTimer.h" @interface HWWeakTimerTarget : NSObject @property (nonatomic, weak) id target; @property (nonatomic, assign) SEL selector; @property (nonatomic, weak) NSTimer* timer; @end @implementation HWWeakTimerTarget - (void) fire:(NSTimer *)timer { if(self.target) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" [self.target performSelector:self.selector withObject:timer.userInfo afterDelay:0.0f]; #pragma clang diagnostic pop } else { [self.timer invalidate]; } } @end @implementation HWWeakTimer + (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats { HWWeakTimerTarget* timerTarget = [[HWWeakTimerTarget alloc] init]; timerTarget.target = aTarget; timerTarget.selector = aSelector; timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval target:timerTarget selector:@selector(fire:) userInfo:userInfo repeats:repeats]; return timerTarget.timer; } + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(HWTimerHandler)block userInfo:(id)userInfo repeats:(BOOL)repeats { NSMutableArray *userInfoArray = [NSMutableArray arrayWithObject:[block copy]]; if (userInfo != nil) { [userInfoArray addObject:userInfo]; } return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(_timerBlockInvoke:) userInfo:[userInfoArray copy] repeats:repeats]; } + (void)_timerBlockInvoke:(NSArray*)userInfo { HWTimerHandler block = userInfo[0]; id info = nil; if (userInfo.count == 2) { info = userInfo[1]; } // or `!block ?: block();` @sunnyxx if (block) { block(info); } } @end