diff --git a/Class Decompile.py b/Class Decompile.py index 35e6689..23255b0 100644 --- a/Class Decompile.py +++ b/Class Decompile.py @@ -3,7 +3,7 @@ import re import gc import os - +import concurrent.futures IGNORED_CLASS_PREFIXES = [ 'AFNetwork', 'AFHTTP', 'AFURL', 'AFSecurity', @@ -44,8 +44,8 @@ def get_file_header(class_name): // %s.m // // Generated by Class Decompile. -// Repository is https://github.com/poboke/Class-Decompile -// Copyright © 2016 www.poboke.com. All rights reserved. +// Repository is https://github.com/erduoniba/Class-Decompile +// Copyright © 2024 www.poboke.com. All rights reserved. // @implementation %s @@ -58,6 +58,13 @@ def get_file_footer(): @end ''' +def write_to_file(file_path, codes): + with open(file_path, 'w', encoding='utf-8') as file: + file.write(codes) + + del codes + gc.collect() + #pragma mark - Decompile @@ -102,35 +109,37 @@ def start_decompile(input_class_name=None): classes.setdefault(class_name, []).append(procedure) total_count += 1 - print 'total count :', total_count + print('total count :', total_count) current_count = 0 - for class_name in classes: - print '\n***** %s *****'%(class_name) - codes = get_file_header(class_name) - procedures = classes[class_name] - for procedure in procedures: - current_count += 1 - percent = (float(current_count) / total_count) * 100 - print '%05.2f%% | %s'%(percent, procedure.label_name) - pseudo_code = procedure.decompile() - if not pseudo_code: - continue - match = re.match(r'.+return\s.+;', pseudo_code, re.DOTALL) - method_type = 'id' if match else 'void' - method_name = procedure.method_name%method_type - codes += '%s\n{\n%s}\n\n'%(method_name, pseudo_code) - codes += get_file_footer() - - file_path = get_file_path(class_name) - with open(file_path, 'w') as file: - file.write(codes) - - del codes - gc.collect() + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [] + for class_name in classes: + print('\n***** %s *****'%(class_name)) + codes = get_file_header(class_name) + procedures = classes[class_name] + for procedure in procedures: + current_count += 1 + percent = (float(current_count) / total_count) * 100 + print('%05.2f%% | %s'%(percent, procedure.label_name)) + pseudo_code = procedure.decompile() + if not pseudo_code: + continue + match = re.match(r'.+return\s.+;', pseudo_code, re.DOTALL) + method_type = 'id' if match else 'void' + method_name = procedure.method_name%method_type + codes += '%s\n{\n%s}\n\n'%(method_name, pseudo_code) + codes += get_file_footer() + + file_path = get_file_path(class_name) + future = executor.submit(write_to_file, file_path, codes) + futures.append(future) + + for future in concurrent.futures.as_completed(futures): + future.result() os.system('open "%s"'%(path)) - print 'Done!' + print('Done!') document = Document.getCurrentDocument() @@ -152,11 +161,11 @@ def start_decompile(input_class_name=None): message = 'Please input the class name:' input_class_name = document.ask(message) if input_class_name is None: - print 'Cancel decompile!' + print('Cancel decompile!') elif input_class_name == '': - print 'Class name can not be empty!' + print('Class name can not be empty!') else: start_decompile(input_class_name) elif button_index == 2: - print 'Cancel decompile!' + print('Cancel decompile!')