diff --git a/FBRetainCycleDetector/Layout/Classes/FBClassStrongLayout.mm b/FBRetainCycleDetector/Layout/Classes/FBClassStrongLayout.mm index a1feacf..f377021 100644 --- a/FBRetainCycleDetector/Layout/Classes/FBClassStrongLayout.mm +++ b/FBRetainCycleDetector/Layout/Classes/FBClassStrongLayout.mm @@ -146,7 +146,8 @@ static NSUInteger FBGetMinimumIvarIndex(__unsafe_unretained Class aCls) { if (count > 0) { Ivar ivar = ivars[0]; ptrdiff_t offset = ivar_getOffset(ivar); - minimumIndex = offset / (sizeof(void *)); + // unaligned bytes at the start of this class's ivars are not represented in the layout bitmap. + minimumIndex = (offset + (sizeof(void *) - 1)) / (sizeof(void *)); } free(ivars); diff --git a/FBRetainCycleDetectorTests/FBClassStrongLayoutTests.mm b/FBRetainCycleDetectorTests/FBClassStrongLayoutTests.mm index 07ac1d5..d2bbe6d 100644 --- a/FBRetainCycleDetectorTests/FBClassStrongLayoutTests.mm +++ b/FBRetainCycleDetectorTests/FBClassStrongLayoutTests.mm @@ -13,6 +13,7 @@ #import #import +#import @interface _RCDTestEmptyClass : NSObject @end @@ -157,6 +158,22 @@ @implementation _RCDTestClassWithCppStructAndStrongProperty } @end +@interface _RCDTestClassWithUnalignEndIvar : NSObject { + char content[20]; +} +@end +@implementation _RCDTestClassWithUnalignEndIvar +@end + +@interface _RCDTestClassWithUnalignEndIvarParentClass : _RCDTestClassWithUnalignEndIvar { + int integer; + __weak NSObject *object1; + NSObject *object2; +} +@end +@implementation _RCDTestClassWithUnalignEndIvarParentClass +@end + @interface FBClassStrongLayoutTests : XCTestCase @end @@ -260,4 +277,11 @@ - (void)testLayoutForClassWithCppStructAndStrongPropertyWillNotCrashAndFetchStro XCTAssertEqual([ivars count], 1); } +- (void)testLayoutForClassWithParentClassHasUnalignEndIvar +{ + NSArray> *ivars = FBGetObjectStrongReferences([_RCDTestClassWithUnalignEndIvarParentClass new], nil); + XCTAssertEqual([ivars count], 1); + XCTAssertEqualObjects([[ivars firstObject] namePath], @[@"object2"]); +} + @end