Remove background deallocation helper code (#1890) · TextureGroup/Texture@9ef97f4 · GitHub
Skip to content

Commit 9ef97f4

Browse files
author
Greg Bolsinga
authored
Remove background deallocation helper code (#1890)
* Remove background deallocation helper code Last use removed in Texture with #1840, now PINS no longer uses it either. Less OOMs is so nice. * remove methods from docs
1 parent f56a4dd commit 9ef97f4

8 files changed

Lines changed: 1 addition & 114 deletions

File tree

‎Source/ASRunLoopQueue.h‎

Lines changed: 1 addition & 12 deletions

‎Source/ASRunLoopQueue.mm‎

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -27,67 +27,6 @@ static void runLoopSourceCallback(void *info) {
2727
#endif
2828
}
2929

30-
#pragma mark - ASDeallocQueue
31-
32-
@implementation ASDeallocQueue {
33-
std::vector<CFTypeRef> _queue;
34-
AS::Mutex _lock;
35-
}
36-
37-
+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED
38-
{
39-
static ASDeallocQueue *deallocQueue = nil;
40-
static dispatch_once_t onceToken;
41-
dispatch_once(&onceToken, ^{
42-
deallocQueue = [[ASDeallocQueue alloc] init];
43-
});
44-
return deallocQueue;
45-
}
46-
47-
- (void)dealloc
48-
{
49-
ASDisplayNodeFailAssert(@"Singleton should not dealloc.");
50-
}
51-
52-
- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
53-
{
54-
NSParameterAssert(objectPtr != NULL);
55-
56-
// Cast to CFType so we can manipulate retain count manually.
57-
const auto cfPtr = (CFTypeRef *)(void *)objectPtr;
58-
if (!cfPtr || !*cfPtr) {
59-
return;
60-
}
61-
62-
_lock.lock();
63-
const auto isFirstEntry = _queue.empty();
64-
// Push the pointer into our queue and clear their pointer.
65-
// This "steals" the +1 from ARC and nils their pointer so they can't
66-
// access or release the object.
67-
_queue.push_back(*cfPtr);
68-
*cfPtr = NULL;
69-
_lock.unlock();
70-
71-
if (isFirstEntry) {
72-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.100 * NSEC_PER_SEC)), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
73-
[self drain];
74-
});
75-
}
76-
}
77-
78-
- (void)drain
79-
{
80-
_lock.lock();
81-
const auto q = std::move(_queue);
82-
_lock.unlock();
83-
for (CFTypeRef ref : q) {
84-
// NOTE: Could check that retain count is 1 and retry later if not.
85-
CFRelease(ref);
86-
}
87-
}
88-
89-
@end
90-
9130
@implementation ASAbstractRunLoopQueue
9231

9332
- (instancetype)init

‎Source/Private/ASInternalHelpers.h‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ ASDK_EXTERN void ASPerformBlockOnMainThread(void (^block)(void));
3434
/// Dispatches the given block to a background queue with priority of DISPATCH_QUEUE_PRIORITY_DEFAULT if not already run on a background queue
3535
ASDK_EXTERN void ASPerformBlockOnBackgroundThread(void (^block)(void)); // DISPATCH_QUEUE_PRIORITY_DEFAULT
3636

37-
/// For deallocation of objects on a background thread without GCD overhead / thread explosion
38-
ASDK_EXTERN void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object);
39-
4037
ASDK_EXTERN CGFloat ASScreenScale(void);
4138

4239
ASDK_EXTERN CGSize ASFloorSizeValues(CGSize s);

‎Source/Private/ASInternalHelpers.mm‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,6 @@ void ASPerformBlockOnBackgroundThread(void (^block)(void))
140140
}
141141
}
142142

143-
void ASPerformBackgroundDeallocation(id __strong _Nullable * _Nonnull object)
144-
{
145-
[[ASDeallocQueue sharedDeallocationQueue] releaseObjectInBackground:object];
146-
}
147-
148143
Class _Nullable ASGetClassFromType(const char * _Nullable type)
149144
{
150145
// Class types all start with @"

‎Tests/Common/ASTestCase.mm‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,6 @@ - (void)invokeTest
8585
@autoreleasepool {
8686
[super invokeTest];
8787
}
88-
89-
// Now that the autorelease pool is drained, drain the dealloc queue also.
90-
[[ASDeallocQueue sharedDeallocationQueue] drain];
9188
}
9289

9390
+ (ASTestCase *)currentTestCase

‎docs/_docs/development/how-to-debug.md‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,6 @@ Here is the collection view's `dealloc`
7575
[self setAsyncDelegate:nil];
7676
[self setAsyncDataSource:nil];
7777
}
78-
79-
// Data controller & range controller may own a ton of nodes, let's deallocate those off-main.
80-
ASPerformBackgroundDeallocation(&_dataController);
81-
ASPerformBackgroundDeallocation(&_rangeController);
8278
}
8379
```
8480

‎docs/_docs/development/node-lifecycle.md‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,6 @@ For more details, look into ASCollectionLayout, ASCollectionGalleryLayoutDelegat
3131

3232
As mentioned above, since ASCellNodes are not meant to be reused, they have a longer lifecycle compared to the view or layer that they encapsulate or their corresponding UICollectionViewCell or UITableViewCell. ASCellNodes are deallocated when they are no longer used and removed from the container node. This can occur after a batch update that includes a reload data or deletion, or after the container node is no longer used and thus released.
3333

34-
For the latter case in which the container node is no longer used and thus released, their cell nodes are not released immediately. That is because collection and table nodes might hold a large number of cell nodes and releasing all of them (and their subnodes, more on this later) at the same time can cause a noticeable delay. To avoid that, ASCollectionNode and ASTableNode release their instance variables, most noticeably an ASDataController instance, on a background thread using a helper called ASDeallocQueue. Since the ASDataController instance is the true owner of all cell nodes -- it has a strong reference to all of them --, all of those cell nodes are deallocated off the main thread as well. As a result, you can expect a delay from which a collection or table view is released until all the cell nodes are fully released and their memory reclaimed. It's important to remember this when debugging memory leaks: objects referenced by the data controller may take a bit to show as dealloced by Instruments.
35-
36-
## ASDeallocQueue
37-
38-
As mentioned above, ASDeallocQueue helps to defer the deallocation of objects given to it by increasing the reference count of each object -- essentially retaining them and acting as their sole owner -- and then release them later on a background thread.
39-
4034
# Nodes that are not managed by containers
4135

4236
These are nodes that are often directly created by client code, such as direct and indirect subnodes of cell nodes. When a node is added to a parent node, the parent node retains it until it's removed from the parent node, or until the parent node is deallocated. As a result, if the subnode is not retained by client code in any other way or if it's not removed from the parent node, the subnode's lifecycle is tied to the parent node's lifecycle. In addition, since nodes often live in a hierarchy, the entire node hierarchy has the same lifecycle as the root node's. Lastly, if the root node is managed by a node container -- directly in the case of ASDKViewController and the like, or indirectly as a cell node of a collection or table node --, then the entire node hierarchy is managed by the node container.

‎docs/_docs/development/threading.md‎

Lines changed: 0 additions & 20 deletions

0 commit comments

Comments
 (0)