diff --git a/CHANGES.rst b/CHANGES.rst index da9cff9b0..c14bb4dc8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,7 +5,7 @@ Changes to be released in next version * 🙌 Improvements - * + * MXCollectionViewCell: Reduced disk access when creating cells by caching UINib objects. 🐛 Bugfix * diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index d58f89f03..5b3c3538f 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,4 +1,4 @@ Contributing code to the Matrix iOS Kit ======================================= -matrix-ios-kit follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.rst +matrix-ios-kit follows the same pattern as https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md diff --git a/MatrixKit/Views/MXKCollectionViewCell/MXKCollectionViewCell.m b/MatrixKit/Views/MXKCollectionViewCell/MXKCollectionViewCell.m index e18f68927..21deecc79 100644 --- a/MatrixKit/Views/MXKCollectionViewCell/MXKCollectionViewCell.m +++ b/MatrixKit/Views/MXKCollectionViewCell/MXKCollectionViewCell.m @@ -21,14 +21,28 @@ @implementation MXKCollectionViewCell + (UINib *)nib { - // Check whether a nib file is available - NSBundle *mainBundle = [NSBundle bundleForClass:self.class]; - NSString *path = [mainBundle pathForResource:NSStringFromClass([self class]) ofType:@"nib"]; - if (path) + NSParameterAssert(NSThread.isMainThread); + + // Nib cache lives forever. UINibs release resources on demand. Null means there is no nib. + static NSMutableDictionary *nibs; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + nibs = [[NSMutableDictionary alloc] init]; + }); + + id result = nibs[(id)self]; + if (!result) { - return [UINib nibWithNibName:NSStringFromClass([self class]) bundle:mainBundle]; + NSString *className = NSStringFromClass(self); + NSBundle *bundle = [NSBundle bundleForClass:self]; + NSString *path = [bundle pathForResource:className ofType:@"nib"]; + if (path) + { + result = [UINib nibWithNibName:className bundle:bundle]; + } + nibs[(id)self] = result ?: [NSNull null]; } - return nil; + return result == [NSNull null] ? nil : result; } + (NSString*)defaultReuseIdentifier @@ -53,9 +67,10 @@ - (void)prepareForReuse - (instancetype)initWithFrame:(CGRect)frame { // Check whether a xib is defined - if ([[self class] nib]) + UINib *nib = [self.class nib]; + if (nib) { - self = [[[self class] nib] instantiateWithOwner:nil options:nil].firstObject; + self = [nib instantiateWithOwner:nil options:nil].firstObject; self.frame = frame; } else