Last active
May 16, 2019 13:11
-
-
Save hankbao/0d10ff7c762207ac23eb9a5a447a63fe to your computer and use it in GitHub Desktop.
Autorelease Pool which doesn't work...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AutoreleasePool.h | |
// | |
// Created by Hank Bao | |
// Copyright (c) 2019 zTap studio. All rights reserved. | |
// | |
#ifndef AUTORELEASE_POOL_H | |
#define AUTORELEASE_POOL_H | |
#ifdef __cplusplus | |
extern "C" { | |
#endif // __clpusplus | |
#ifdef __APPLE__ | |
void autoreleasepool_push(void); | |
void autoreleasepool_pop(void); | |
#define AUTORELEASEPOOL_PUSH() autoreleasepool_push() | |
#define AUTORELEASEPOOL_POP() autoreleasepool_pop() | |
#else | |
#define AUTORELEASEPOOL_PUSH() | |
#define AUTORELEASEPOOL_POP() | |
#endif // __APPLE__ | |
#ifdef __cplusplus | |
} | |
#endif // __clpusplus | |
#endif AUTORELEASE_POOL_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AutoreleasePool.m | |
// | |
// Created by Hank Bao | |
// Copyright (c) 2019 zTap studio. All rights reserved. | |
// | |
@import Foundation; | |
#import "AutoreleasePool.h" | |
static NSString * const kAutoreleasePoolThreadDictionaryKey = @"net.ztap.autoreleasepool"; | |
static NSString * const kAutoreleasePoolException = @"net.ztap.exception.autoreleasepool"; | |
static void* _autorelease_pool_class; | |
typedef void* (*pool_imp_new)(void*, void*); | |
static pool_imp_new _autorelease_pool_imp_new; | |
static SEL _autorelease_pool_sel_new; | |
typedef void (*pool_imp_drain)(void*, void*); | |
static pool_imp_drain _autorelease_pool_imp_drain; | |
static SEL _autorelease_pool_sel_drain; | |
@interface AutoreleasePoolWrapper : NSObject { | |
void* payload; // the real pool | |
} | |
@end | |
@implementation AutoreleasePoolWrapper | |
- (instancetype)init { | |
if (self = [super init]) { | |
payload = _autorelease_pool_imp_new(_autorelease_pool_class, _autorelease_pool_sel_new); | |
} | |
return self; | |
} | |
- (void)dealloc { | |
if (payload) { | |
_autorelease_pool_imp_drain(payload, _autorelease_pool_sel_drain); | |
payload = NULL; | |
} | |
} | |
@end | |
@interface AutoreleasePool : NSObject | |
+ (void)push; | |
+ (void)pop; | |
@end | |
@implementation AutoreleasePool | |
+ (void)initialize { | |
if (self == [AutoreleasePool self]) { | |
_autorelease_pool_class = (__bridge void *)(NSClassFromString(@"NSAutoreleasePool")); | |
_autorelease_pool_sel_new = @selector(new); | |
_autorelease_pool_imp_new = (pool_imp_new) [NSClassFromString(@"NSAutoreleasePool") | |
methodForSelector:_autorelease_pool_sel_new]; | |
_autorelease_pool_sel_drain = @selector(drain); | |
_autorelease_pool_imp_drain = (pool_imp_drain) [NSClassFromString(@"NSAutoreleasePool") | |
instanceMethodForSelector:_autorelease_pool_sel_drain];; | |
} | |
} | |
+ (NSMutableArray*)poolsForCurrentThread { | |
NSMutableDictionary* threadDict = NSThread.currentThread.threadDictionary; | |
NSMutableArray* pools = threadDict[kAutoreleasePoolThreadDictionaryKey]; | |
if (!pools) { | |
pools = [NSMutableArray new]; | |
threadDict[kAutoreleasePoolThreadDictionaryKey] = pools; | |
} | |
return pools; | |
} | |
+ (void)push { | |
AutoreleasePoolWrapper* pool = [AutoreleasePoolWrapper new]; | |
if (pool) { | |
[[self poolsForCurrentThread] addObject:pool]; | |
} | |
} | |
+ (void)pop { | |
NSMutableArray* pools = [self poolsForCurrentThread]; | |
if (!pools.lastObject) { | |
[NSException raise:kAutoreleasePoolException format:@"autoreleasepool unbalanced pop"]; | |
} | |
[pools removeLastObject]; | |
} | |
@end | |
void autoreleasepool_push(void) { | |
[AutoreleasePool push]; | |
} | |
void autoreleasepool_pop(void) { | |
[AutoreleasePool pop]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment