² %new
%new is used inside %hook to add a new method to an existing class; it’s the same as
class_addMethod, for example:
%hook SpringBoard
%new
- (void)namespaceNewMethod
{
NSLog(@"We’ve added a new method to SpringBoard.");
}
%end
Some of you may wonder, category in Objective-C can already add new methods to classes,
why do we still need %new? The difference between category and %new is that the former is
static while the latter is dynamic. Well, does static adding or dynamic adding matter? Yes,
especially when the class to be added is from a certain executable, it matters. For example, the
above code adds a new method to SpringBoard. If we use category, the code should look like
this:
@interface SpringBoard (iOSRE)
- (void)namespaceNewMethod;
@end
@implementation SpringBoard (iOSRE)
- (void)namespaceNewMethod
{
NSLog(@"We’ve added a new method to SpringBoard.");
}
@end
We will get “error: cannot find interface declaration for ‘SpringBoard’” when trying to
compile the above code, which indicates that the compiler cannot find the definition of
SpringBoard. We can compose a SpringBoard class to cheat the compiler:
@interface SpringBoard : NSObject
@end
@interface SpringBoard (iOSRE)
- (void)namespaceNewMethod;
@end
@implementation SpringBoard (iOSRE)
- (void)namespaceNewMethod
{
NSLog(@"We’ve added a new method to SpringBoard.");
}
@end
Recompile it, we’ll still get the following error:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_SpringBoard", referenced from:
l_OBJC_$_CATEGORY_SpringBoard_$_iOSRE in Tweak.xm.b1748661.o