NSOperation에 백그라운드에서 시간 간격으로 실행되는 기능을 제공하는 범주를 개발했습니다. 이 문제에 대한 의견을 듣고 싶습니다. 특히이 접근법에 대한 잠재적 인 문제는 생각지 못합니다.반복 옵션이있는 NSOperation
감사합니다. 여기
코드입니다 :NSOperation + Repeat.h
#import <Foundation/Foundation.h>
@interface NSOperation (repeat)
@property (readonly, nonatomic) NSTimeInterval repeatInterval;
@property (readonly, nonatomic) NSOperationQueue *repeatOperationQueue;
- (void)performUsingOperationQueue:(NSOperationQueue *)operationQueue;
- (void)performAtRepeatingInterval:(NSTimeInterval)interval usingOperationQueue:(NSOperationQueue *)operationQueue;
@end
NSOperation + 여기서 반복 할 수있는 NSOperation 하위 클래스의 예 Repeat.m
#import "NSOperation+repeat.h"
#import <objc/runtime.h>
static char const * const RepeatPropertiesKey = "RepeatProperties";
@implementation NSOperation (repeat)
@dynamic repeatInterval;
@dynamic repeatOperationQueue;
static NSString * RepeatIntervalKey = @"interval";
static NSString * RepeatOperationQueueKey = @"operationQueue";
static NSString * RepeatTimerKey = @"timer";
- (NSMutableDictionary *)repeatProperties {
NSMutableDictionary * properties = objc_getAssociatedObject(self, RepeatPropertiesKey);
if (properties == nil) {
properties = [NSMutableDictionary new];
objc_setAssociatedObject(self, RepeatPropertiesKey, properties, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return properties;
}
- (NSTimeInterval)interval {
NSNumber * interval = [[self repeatProperties] objectForKey:RepeatIntervalKey];
return [interval doubleValue];
}
- (NSOperationQueue *)repeatOperationQueue {
NSOperationQueue * operationQueue = [[self repeatProperties] objectForKey:RepeatOperationQueueKey];
return operationQueue;
}
- (void)performUsingOperationQueue:(NSOperationQueue *)operationQueue {
[operationQueue addOperation:[self copy]];
}
- (void)performAtInterval:(NSTimer *)timer {
[self performUsingOperationQueue:self.repeatOperationQueue];
}
- (void)performAtRepeatingInterval:(NSTimeInterval)interval usingOperationQueue:(NSOperationQueue *)operationQueue {
// Save interval and operationQueue in repeatProperties
[self.repeatProperties setValue:[NSNumber numberWithDouble:interval] forKey:RepeatIntervalKey];
[self.repeatProperties setValue:operationQueue forKey:RepeatOperationQueueKey];
// Create timer to call performAtInterval on self
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(interval*60)
target:self
selector:@selector(performAtInterval:)
userInfo:nil
repeats:YES];
// Save the timer in repeatProperties
[self.repeatProperties setValue:timer forKey:RepeatTimerKey];
[self performUsingOperationQueue:operationQueue];
}
@end
:
가MSScheduleImportOperation.h
,210#import <Foundation/Foundation.h>
#import "NSOperation+Repeat.h"
@interface MSScheduleImportOperation : NSOperation <NSCopying>
@property (readonly, strong, nonatomic) NSString* employeeId;
- (id)initWithEmployeeId:(NSString *)employeeId;
@end
MSScheduleImportOperation.m
#import "MSScheduleImportOperation.h"
@implementation MSScheduleImportOperation
@synthesize employeeId = __employeeId;
- (id)initWithEmployeeId:(NSString *)employeeId {
self = [super init];
__employeeId = [employeeId copy];
return self;
}
- (id)copyWithZone:(NSZone *)zone {
MSScheduleImportOperation* copy = [[MSScheduleImportOperation alloc] initWithEmployeeId:self.employeeId];
return copy;
}
- (void)main
{
...
}
@end
꽤 많은 문제점을 볼 수 있습니다. 우선, 대부분의 하위 클래스가 지원하지 않는 NSOperation 사본을 만들고 있습니다. 둘째, 취소를 처리하지 않는 것 같습니다. 작업이 취소되면이 코드는 계속해서 더 많은 인스턴스를 생성합니다. 셋째, 작업을 완료하는 데 시간이 오래 걸리면이 코드가 더 많은 인스턴스를 생성하고 동시에 여러 작업을 실행하게됩니다. –
예, NSOperation의 하위 클래스는 NSCopying 프로토콜로 정의하고 (id) copyWithZone : (NSZone *) 영역을 구현해야합니다. – ScottD
취소시 추가해야합니다.타이머를 반복적으로 멈추게하기 위해 nil을 할당 할 수 있어야합니다. – ScottD