苹果私有函数使用初探
在OSX或者IOS的开发过程中,有时为了解决一些棘手的问题,在没有其他可选方法的情况下,不得不使用苹果的私有函数。 当然使用的话,在审核的过程中,肯定会被毙掉的。面对如何尴尬的问题,该如何解决呢。
本文只是介绍一些可能规避的方法,建议不要直接使用显而易见的关键字(比如_NSThemeCloseWidget、_NSThemeZoomWidget等等),可以采用混淆的方法,比如直接使用NSData类型的,用到的时候再通过如下代码转换一下。
NSClassFromString([[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding])
或者使用字符串的拼接,打乱之前的顺序等等方法,反正确保不要从字面上就可以轻易的看出来。
最后附上对上一篇按钮的Hover状态解决办法的代码:
CFStringRef (* originalIMP)(id self, SEL _cmd);
NSMutableData *stateOneData;
NSMutableData *stateTwoData;
NSMutableData *stateThreeData;
-(void)initSwizzingMethod {
NSString * strOne = @"5f4e5354 68656d65 57696467 65744365 6c6c";
NSString *strTwo = @"636f7265 55495374 617465";
NSString *stateOne = @"6e6f726d 616c";
NSString *stateTwo = @"726f6c6c 6f766572";
NSString *stateThree = @"70726573 736564" ;
NSMutableData *dataOne = [[NSMutableData alloc]init];
NSMutableData *dataTwo = [[NSMutableData alloc]init];
stateOneData = [[NSMutableData alloc]init];
stateTwoData = [[NSMutableData alloc]init];
stateThreeData = [[NSMutableData alloc]init];
//@"_NSThemeWidgetCell"
[self convertFunctionDataFromString:strOne result:dataOne];
//@"coreUIState"
[self convertFunctionDataFromString:strTwo result:dataTwo];
//@"pressed"
[self convertFunctionDataFromString:stateOne result:stateOneData];
//@"rollover"
[self convertFunctionDataFromString:stateTwo result:stateTwoData];
//@"normal"
[self convertFunctionDataFromString:stateThree result:stateThreeData];
Method stateMethod = class_getInstanceMethod(
NSClassFromString([[NSString alloc]initWithData:dataOne encoding:NSUTF8StringEncoding]),
NSSelectorFromString([[NSString alloc]initWithData:dataTwo encoding:NSUTF8StringEncoding]));
const char *encoding = method_getTypeEncoding(stateMethod);
originalIMP = (void*)method_getImplementation(stateMethod);
class_replaceMethod(
NSClassFromString([[NSString alloc]initWithData:dataOne encoding:NSUTF8StringEncoding]),
NSSelectorFromString([[NSString alloc]initWithData:dataTwo encoding:NSUTF8StringEncoding]),
(IMP)methodState,
encoding);
}
static CFStringRef methodState(id self, SEL _cmd) {
if ([self isKindOfClass:[NSButtonCell class]]) {
NSButtonCell *cell = (NSButtonCell*)self;
NSString *title = [cell title];
if ([title isEqualToString:@"CUSTOM_BUTTON"]) {
if (cell.highlighted) {
return (__bridge_retained CFStringRef)([[NSString alloc]initWithData:stateThreeData encoding:NSUTF8StringEncoding]);
} else if (cell.state) {
return (__bridge_retained CFStringRef)([[NSString alloc]initWithData:stateTwoData encoding:NSUTF8StringEncoding]);
} else {
return (__bridge_retained CFStringRef)([[NSString alloc]initWithData:stateOneData encoding:NSUTF8StringEncoding]);
}
}
}
return originalIMP(self,_cmd);
}
//以下几个函数用于转换
-(NSData*)converData:(NSString*)str {
unsigned int value;
NSScanner *scanner = [NSScanner scannerWithString:str];
[scanner scanHexInt:&value];
NSString *convertStr = [NSString stringWithFormat:@"%c",value];
NSData *data = [convertStr dataUsingEncoding:NSUTF8StringEncoding];
return data;
}
-(void)convertDataFromString:(NSString*)str
resultData:(NSMutableData*)resultData {
if (str.length <= 2) {
NSData *data = [self converData:str];
[resultData appendData:data];
return;
}
NSString *str1 = [str substringWithRange:NSMakeRange(0, 2)];
[self convertDataFromString:str1
resultData:resultData];
NSString *str2 = [str substringFromIndex:2];
[self convertDataFromString:str2
resultData:resultData];
}
-(void)convertFunctionDataFromString:(NSString*)str
result:(NSMutableData*)data {
[str enumerateSubstringsInRange:(NSMakeRange(0, str.length))
options:NSStringEnumerationByWords
usingBlock:^(NSString *substring,
NSRange substringRange,
NSRange enclosingRange,
BOOL *stop) {
[self convertDataFromString:substring
resultData:data];
}];
}
转载请注明出处:http://blog.csdn.net/skynullcode