You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

302 lines
12 KiB

//
// NSObject+YYAdd.h
// YYKit <https://github.com/ibireme/YYKit>
//
// 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 <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
Common tasks for NSObject.
*/
@interface NSObject (YYAdd)
#pragma mark - Sending messages with variable parameters
///=============================================================================
/// @name Sending messages with variable parameters
///=============================================================================
/**
Sends a specified message to the receiver and returns the result of the message.
@param sel A selector identifying the message to send. If the selector is
NULL or unrecognized, an NSInvalidArgumentException is raised.
@param ... Variable parameter list. Parameters type must correspond to the
selector's method declaration, or unexpected results may occur.
It doesn't support union or struct which is larger than 256 bytes.
@return An object that is the result of the message.
@discussion The selector's return value will be wrap as NSNumber or NSValue
if the selector's `return type` is not object. It always returns nil
if the selector's `return type` is void.
Sample Code:
// no variable args
[view performSelectorWithArgs:@selector(removeFromSuperView)];
// variable arg is not object
[view performSelectorWithArgs:@selector(setCenter:), CGPointMake(0, 0)];
// perform and return object
UIImage *image = [UIImage.class performSelectorWithArgs:@selector(imageWithData:scale:), data, 2.0];
// perform and return wrapped number
NSNumber *lengthValue = [@"hello" performSelectorWithArgs:@selector(length)];
NSUInteger length = lengthValue.unsignedIntegerValue;
// perform and return wrapped struct
NSValue *frameValue = [view performSelectorWithArgs:@selector(frame)];
CGRect frame = frameValue.CGRectValue;
*/
- (nullable id)performSelectorWithArgs:(SEL)sel, ...;
/**
Invokes a method of the receiver on the current thread using the default mode after a delay.
@warning It can't cancelled by previous request.
@param sel A selector identifying the message to send. If the selector is
NULL or unrecognized, an NSInvalidArgumentException is raised immediately.
@param delay The minimum time before which the message is sent. Specifying
a delay of 0 does not necessarily cause the selector to be
performed immediately. The selector is still queued on the
thread's run loop and performed as soon as possible.
@param ... Variable parameter list. Parameters type must correspond to the
selector's method declaration, or unexpected results may occur.
It doesn't support union or struct which is larger than 256 bytes.
Sample Code:
// no variable args
[view performSelectorWithArgs:@selector(removeFromSuperView) afterDelay:2.0];
// variable arg is not object
[view performSelectorWithArgs:@selector(setCenter:), afterDelay:0, CGPointMake(0, 0)];
*/
- (void)performSelectorWithArgs:(SEL)sel afterDelay:(NSTimeInterval)delay, ...;
/**
Invokes a method of the receiver on the main thread using the default mode.
@param sel A selector identifying the message to send. If the selector is
NULL or unrecognized, an NSInvalidArgumentException is raised.
@param wait A Boolean that specifies whether the current thread blocks until
after the specified selector is performed on the receiver on the
specified thread. Specify YES to block this thread; otherwise,
specify NO to have this method return immediately.
@param ... Variable parameter list. Parameters type must correspond to the
selector's method declaration, or unexpected results may occur.
It doesn't support union or struct which is larger than 256 bytes.
@return While @a wait is YES, it returns object that is the result of
the message. Otherwise return nil;
@discussion The selector's return value will be wrap as NSNumber or NSValue
if the selector's `return type` is not object. It always returns nil
if the selector's `return type` is void, or @a wait is YES.
Sample Code:
// no variable args
[view performSelectorWithArgsOnMainThread:@selector(removeFromSuperView), waitUntilDone:NO];
// variable arg is not object
[view performSelectorWithArgsOnMainThread:@selector(setCenter:), waitUntilDone:NO, CGPointMake(0, 0)];
*/
- (nullable id)performSelectorWithArgsOnMainThread:(SEL)sel waitUntilDone:(BOOL)wait, ...;
/**
Invokes a method of the receiver on the specified thread using the default mode.
@param sel A selector identifying the message to send. If the selector is
NULL or unrecognized, an NSInvalidArgumentException is raised.
@param thread The thread on which to execute aSelector.
@param wait A Boolean that specifies whether the current thread blocks until
after the specified selector is performed on the receiver on the
specified thread. Specify YES to block this thread; otherwise,
specify NO to have this method return immediately.
@param ... Variable parameter list. Parameters type must correspond to the
selector's method declaration, or unexpected results may occur.
It doesn't support union or struct which is larger than 256 bytes.
@return While @a wait is YES, it returns object that is the result of
the message. Otherwise return nil;
@discussion The selector's return value will be wrap as NSNumber or NSValue
if the selector's `return type` is not object. It always returns nil
if the selector's `return type` is void, or @a wait is YES.
Sample Code:
[view performSelectorWithArgs:@selector(removeFromSuperView) onThread:mainThread waitUntilDone:NO];
[array performSelectorWithArgs:@selector(sortUsingComparator:)
onThread:backgroundThread
waitUntilDone:NO, ^NSComparisonResult(NSNumber *num1, NSNumber *num2) {
return [num2 compare:num2];
}];
*/
- (nullable id)performSelectorWithArgs:(SEL)sel onThread:(NSThread *)thread waitUntilDone:(BOOL)wait, ...;
/**
Invokes a method of the receiver on a new background thread.
@param sel A selector identifying the message to send. If the selector is
NULL or unrecognized, an NSInvalidArgumentException is raised.
@param ... Variable parameter list. Parameters type must correspond to the
selector's method declaration, or unexpected results may occur.
It doesn't support union or struct which is larger than 256 bytes.
@discussion This method creates a new thread in your application, putting
your application into multithreaded mode if it was not already.
The method represented by sel must set up the thread environment
just as you would for any other new thread in your program.
Sample Code:
[array performSelectorWithArgsInBackground:@selector(sortUsingComparator:),
^NSComparisonResult(NSNumber *num1, NSNumber *num2) {
return [num2 compare:num2];
}];
*/
- (void)performSelectorWithArgsInBackground:(SEL)sel, ...;
/**
Invokes a method of the receiver on the current thread after a delay.
@warning arc-performSelector-leaks
@param sel A selector that identifies the method to invoke. The method should
not have a significant return value and should take no argument.
If the selector is NULL or unrecognized,
an NSInvalidArgumentException is raised after the delay.
@param delay The minimum time before which the message is sent. Specifying a
delay of 0 does not necessarily cause the selector to be performed
immediately. The selector is still queued on the thread's run loop
and performed as soon as possible.
@discussion This method sets up a timer to perform the aSelector message on
the current thread's run loop. The timer is configured to run in
the default mode (NSDefaultRunLoopMode). When the timer fires, the
thread attempts to dequeue the message from the run loop and
perform the selector. It succeeds if the run loop is running and
in the default mode; otherwise, the timer waits until the run loop
is in the default mode.
*/
- (void)performSelector:(SEL)sel afterDelay:(NSTimeInterval)delay;
#pragma mark - Swap method (Swizzling)
///=============================================================================
/// @name Swap method (Swizzling)
///=============================================================================
/**
Swap two instance method's implementation in one class. Dangerous, be careful.
@param originalSel Selector 1.
@param newSel Selector 2.
@return YES if swizzling succeed; otherwise, NO.
*/
+ (BOOL)swizzleInstanceMethod:(SEL)originalSel with:(SEL)newSel;
/**
Swap two class method's implementation in one class. Dangerous, be careful.
@param originalSel Selector 1.
@param newSel Selector 2.
@return YES if swizzling succeed; otherwise, NO.
*/
+ (BOOL)swizzleClassMethod:(SEL)originalSel with:(SEL)newSel;
#pragma mark - Associate value
///=============================================================================
/// @name Associate value
///=============================================================================
/**
Associate one object to `self`, as if it was a strong property (strong, nonatomic).
@param value The object to associate.
@param key The pointer to get value from `self`.
*/
- (void)setAssociateValue:(nullable id)value withKey:(void *)key;
/**
Associate one object to `self`, as if it was a weak property (week, nonatomic).
@param value The object to associate.
@param key The pointer to get value from `self`.
*/
- (void)setAssociateWeakValue:(nullable id)value withKey:(void *)key;
/**
Get the associated value from `self`.
@param key The pointer to get value from `self`.
*/
- (nullable id)getAssociatedValueForKey:(void *)key;
/**
Remove all associated values.
*/
- (void)removeAssociatedValues;
#pragma mark - Others
///=============================================================================
/// @name Others
///=============================================================================
/**
Returns the class name in NSString.
*/
+ (NSString *)className;
/**
Returns the class name in NSString.
@discussion Apple has implemented this method in NSObject(NSLayoutConstraintCallsThis),
but did not make it public.
*/
- (NSString *)className;
/**
Returns a copy of the instance with `NSKeyedArchiver` and ``NSKeyedUnarchiver``.
Returns nil if an error occurs.
*/
- (nullable id)deepCopy;
/**
Returns a copy of the instance use archiver and unarchiver.
Returns nil if an error occurs.
@param archiver NSKeyedArchiver class or any class inherited.
@param unarchiver NSKeyedUnarchiver clsas or any class inherited.
*/
- (nullable id)deepCopyWithArchiver:(Class)archiver unarchiver:(Class)unarchiver;
@end
NS_ASSUME_NONNULL_END