From 7b02207537d35bfa1714bf8beafc921f717d100a Mon Sep 17 00:00:00 2001 From: 单军华 Date: Wed, 11 Jul 2018 10:47:42 +0800 Subject: [PATCH] 首次上传 --- screendisplay/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAdd.m | 396 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 396 insertions(+), 0 deletions(-) diff --git a/screendisplay/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAdd.m b/screendisplay/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAdd.m new file mode 100755 index 0000000..7e31e86 --- /dev/null +++ b/screendisplay/Pods/YYCategories/YYCategories/Foundation/NSObject+YYAdd.m @@ -0,0 +1,396 @@ +// +// NSObject+YYAdd.m +// YYCategories <https://github.com/ibireme/YYCategories> +// +// Created by ibireme on 14/10/8. +// Copyright (c) 2015 ibireme. +// +// This source code is licensed under the MIT-style license found in the +// LICENSE file in the root directory of this source tree. +// + +#import "NSObject+YYAdd.h" +#import "YYCategoriesMacro.h" +#import <objc/objc.h> +#import <objc/runtime.h> + +YYSYNTH_DUMMY_CLASS(NSObject_YYAdd) + + +@implementation NSObject (YYAdd) + +/* + NSInvocation is much slower than objc_msgSend()... + Do not use it if you have performance issues. + */ + +#define INIT_INV(_last_arg_, _return_) \ +NSMethodSignature * sig = [self methodSignatureForSelector:sel]; \ +if (!sig) { [self doesNotRecognizeSelector:sel]; return _return_; } \ +NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig]; \ +if (!inv) { [self doesNotRecognizeSelector:sel]; return _return_; } \ +[inv setTarget:self]; \ +[inv setSelector:sel]; \ +va_list args; \ +va_start(args, _last_arg_); \ +[NSObject setInv:inv withSig:sig andArgs:args]; \ +va_end(args); + +- (id)performSelectorWithArgs:(SEL)sel, ...{ + INIT_INV(sel, nil); + [inv invoke]; + return [NSObject getReturnFromInv:inv withSig:sig]; +} + +- (void)performSelectorWithArgs:(SEL)sel afterDelay:(NSTimeInterval)delay, ...{ + INIT_INV(delay, ); + [inv retainArguments]; + [inv performSelector:@selector(invoke) withObject:nil afterDelay:delay]; +} + +- (id)performSelectorWithArgsOnMainThread:(SEL)sel waitUntilDone:(BOOL)wait, ...{ + INIT_INV(wait, nil); + if (!wait) [inv retainArguments]; + [inv performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:wait]; + return wait ? [NSObject getReturnFromInv:inv withSig:sig] : nil; +} + +- (id)performSelectorWithArgs:(SEL)sel onThread:(NSThread *)thr waitUntilDone:(BOOL)wait, ...{ + INIT_INV(wait, nil); + if (!wait) [inv retainArguments]; + [inv performSelector:@selector(invoke) onThread:thr withObject:nil waitUntilDone:wait]; + return wait ? [NSObject getReturnFromInv:inv withSig:sig] : nil; +} + +- (void)performSelectorWithArgsInBackground:(SEL)sel, ...{ + INIT_INV(sel, ); + [inv retainArguments]; + [inv performSelectorInBackground:@selector(invoke) withObject:nil]; +} + +#undef INIT_INV + ++ (id)getReturnFromInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig { + NSUInteger length = [sig methodReturnLength]; + if (length == 0) return nil; + + char *type = (char *)[sig methodReturnType]; + while (*type == 'r' || // const + *type == 'n' || // in + *type == 'N' || // inout + *type == 'o' || // out + *type == 'O' || // bycopy + *type == 'R' || // byref + *type == 'V') { // oneway + type++; // cutoff useless prefix + } + +#define return_with_number(_type_) \ +do { \ +_type_ ret; \ +[inv getReturnValue:&ret]; \ +return @(ret); \ +} while (0) + + switch (*type) { + case 'v': return nil; // void + case 'B': return_with_number(bool); + case 'c': return_with_number(char); + case 'C': return_with_number(unsigned char); + case 's': return_with_number(short); + case 'S': return_with_number(unsigned short); + case 'i': return_with_number(int); + case 'I': return_with_number(unsigned int); + case 'l': return_with_number(int); + case 'L': return_with_number(unsigned int); + case 'q': return_with_number(long long); + case 'Q': return_with_number(unsigned long long); + case 'f': return_with_number(float); + case 'd': return_with_number(double); + case 'D': { // long double + long double ret; + [inv getReturnValue:&ret]; + return [NSNumber numberWithDouble:ret]; + }; + + case '@': { // id + id ret = nil; + [inv getReturnValue:&ret]; + return ret; + }; + + case '#': { // Class + Class ret = nil; + [inv getReturnValue:&ret]; + return ret; + }; + + default: { // struct / union / SEL / void* / unknown + const char *objCType = [sig methodReturnType]; + char *buf = calloc(1, length); + if (!buf) return nil; + [inv getReturnValue:buf]; + NSValue *value = [NSValue valueWithBytes:buf objCType:objCType]; + free(buf); + return value; + }; + } +#undef return_with_number +} + ++ (void)setInv:(NSInvocation *)inv withSig:(NSMethodSignature *)sig andArgs:(va_list)args { + NSUInteger count = [sig numberOfArguments]; + for (int index = 2; index < count; index++) { + char *type = (char *)[sig getArgumentTypeAtIndex:index]; + while (*type == 'r' || // const + *type == 'n' || // in + *type == 'N' || // inout + *type == 'o' || // out + *type == 'O' || // bycopy + *type == 'R' || // byref + *type == 'V') { // oneway + type++; // cutoff useless prefix + } + + BOOL unsupportedType = NO; + switch (*type) { + case 'v': // 1: void + case 'B': // 1: bool + case 'c': // 1: char / BOOL + case 'C': // 1: unsigned char + case 's': // 2: short + case 'S': // 2: unsigned short + case 'i': // 4: int / NSInteger(32bit) + case 'I': // 4: unsigned int / NSUInteger(32bit) + case 'l': // 4: long(32bit) + case 'L': // 4: unsigned long(32bit) + { // 'char' and 'short' will be promoted to 'int'. + int arg = va_arg(args, int); + [inv setArgument:&arg atIndex:index]; + } break; + + case 'q': // 8: long long / long(64bit) / NSInteger(64bit) + case 'Q': // 8: unsigned long long / unsigned long(64bit) / NSUInteger(64bit) + { + long long arg = va_arg(args, long long); + [inv setArgument:&arg atIndex:index]; + } break; + + case 'f': // 4: float / CGFloat(32bit) + { // 'float' will be promoted to 'double'. + double arg = va_arg(args, double); + float argf = arg; + [inv setArgument:&argf atIndex:index]; + } break; + + case 'd': // 8: double / CGFloat(64bit) + { + double arg = va_arg(args, double); + [inv setArgument:&arg atIndex:index]; + } break; + + case 'D': // 16: long double + { + long double arg = va_arg(args, long double); + [inv setArgument:&arg atIndex:index]; + } break; + + case '*': // char * + case '^': // pointer + { + void *arg = va_arg(args, void *); + [inv setArgument:&arg atIndex:index]; + } break; + + case ':': // SEL + { + SEL arg = va_arg(args, SEL); + [inv setArgument:&arg atIndex:index]; + } break; + + case '#': // Class + { + Class arg = va_arg(args, Class); + [inv setArgument:&arg atIndex:index]; + } break; + + case '@': // id + { + id arg = va_arg(args, id); + [inv setArgument:&arg atIndex:index]; + } break; + + case '{': // struct + { + if (strcmp(type, @encode(CGPoint)) == 0) { + CGPoint arg = va_arg(args, CGPoint); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(CGSize)) == 0) { + CGSize arg = va_arg(args, CGSize); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(CGRect)) == 0) { + CGRect arg = va_arg(args, CGRect); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(CGVector)) == 0) { + CGVector arg = va_arg(args, CGVector); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(CGAffineTransform)) == 0) { + CGAffineTransform arg = va_arg(args, CGAffineTransform); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(CATransform3D)) == 0) { + CATransform3D arg = va_arg(args, CATransform3D); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(NSRange)) == 0) { + NSRange arg = va_arg(args, NSRange); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(UIOffset)) == 0) { + UIOffset arg = va_arg(args, UIOffset); + [inv setArgument:&arg atIndex:index]; + } else if (strcmp(type, @encode(UIEdgeInsets)) == 0) { + UIEdgeInsets arg = va_arg(args, UIEdgeInsets); + [inv setArgument:&arg atIndex:index]; + } else { + unsupportedType = YES; + } + } break; + + case '(': // union + { + unsupportedType = YES; + } break; + + case '[': // array + { + unsupportedType = YES; + } break; + + default: // what?! + { + unsupportedType = YES; + } break; + } + + if (unsupportedType) { + // Try with some dummy type... + + NSUInteger size = 0; + NSGetSizeAndAlignment(type, &size, NULL); + +#define case_size(_size_) \ +else if (size <= 4 * _size_ ) { \ + struct dummy { char tmp[4 * _size_]; }; \ + struct dummy arg = va_arg(args, struct dummy); \ + [inv setArgument:&arg atIndex:index]; \ +} + if (size == 0) { } + case_size( 1) case_size( 2) case_size( 3) case_size( 4) + case_size( 5) case_size( 6) case_size( 7) case_size( 8) + case_size( 9) case_size(10) case_size(11) case_size(12) + case_size(13) case_size(14) case_size(15) case_size(16) + case_size(17) case_size(18) case_size(19) case_size(20) + case_size(21) case_size(22) case_size(23) case_size(24) + case_size(25) case_size(26) case_size(27) case_size(28) + case_size(29) case_size(30) case_size(31) case_size(32) + case_size(33) case_size(34) case_size(35) case_size(36) + case_size(37) case_size(38) case_size(39) case_size(40) + case_size(41) case_size(42) case_size(43) case_size(44) + case_size(45) case_size(46) case_size(47) case_size(48) + case_size(49) case_size(50) case_size(51) case_size(52) + case_size(53) case_size(54) case_size(55) case_size(56) + case_size(57) case_size(58) case_size(59) case_size(60) + case_size(61) case_size(62) case_size(63) case_size(64) + else { + /* + Larger than 256 byte?! I don't want to deal with this stuff up... + Ignore this argument. + */ + struct dummy {char tmp;}; + for (int i = 0; i < size; i++) va_arg(args, struct dummy); + NSLog(@"YYCategories performSelectorWithArgs unsupported type:%s (%lu bytes)", + [sig getArgumentTypeAtIndex:index],(unsigned long)size); + } +#undef case_size + + } + } +} + +- (void)performSelector:(SEL)selector afterDelay:(NSTimeInterval)delay { + [self performSelector:selector withObject:nil afterDelay:delay]; +} + ++ (BOOL)swizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel { + Method originalMethod = class_getInstanceMethod(self, originalSel); + Method newMethod = class_getInstanceMethod(self, newSel); + if (!originalMethod || !newMethod) return NO; + + class_addMethod(self, + originalSel, + class_getMethodImplementation(self, originalSel), + method_getTypeEncoding(originalMethod)); + class_addMethod(self, + newSel, + class_getMethodImplementation(self, newSel), + method_getTypeEncoding(newMethod)); + + method_exchangeImplementations(class_getInstanceMethod(self, originalSel), + class_getInstanceMethod(self, newSel)); + return YES; +} + ++ (BOOL)swizzleClassMethod:(SEL)originalSel with:(SEL)newSel { + Class class = object_getClass(self); + Method originalMethod = class_getInstanceMethod(class, originalSel); + Method newMethod = class_getInstanceMethod(class, newSel); + if (!originalMethod || !newMethod) return NO; + method_exchangeImplementations(originalMethod, newMethod); + return YES; +} + +- (void)setAssociateValue:(id)value withKey:(void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)setAssociateWeakValue:(id)value withKey:(void *)key { + objc_setAssociatedObject(self, key, value, OBJC_ASSOCIATION_ASSIGN); +} + +- (void)removeAssociatedValues { + objc_removeAssociatedObjects(self); +} + +- (id)getAssociatedValueForKey:(void *)key { + return objc_getAssociatedObject(self, key); +} + ++ (NSString *)className { + return NSStringFromClass(self); +} + +- (NSString *)className { + return [NSString stringWithUTF8String:class_getName([self class])]; +} + +- (id)deepCopy { + id obj = nil; + @try { + obj = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:self]]; + } + @catch (NSException *exception) { + NSLog(@"%@", exception); + } + return obj; +} + +- (id)deepCopyWithArchiver:(Class)archiver unarchiver:(Class)unarchiver { + id obj = nil; + @try { + obj = [unarchiver unarchiveObjectWithData:[archiver archivedDataWithRootObject:self]]; + } + @catch (NSException *exception) { + NSLog(@"%@", exception); + } + return obj; +} + +@end -- Gitblit v1.8.0