The always wonderful John Holdsworth has put together a replacement ivar_getTypeEncoding() written for Swift classes as part of his XprobePlugin pack. He tells me this is under an MIT license. Update: John asks me to change that to public domain.
/***************************************************** ********* ivar_getTypeEncoding() for swift ********** *****************************************************/ struct _swift_class; struct _swift_type { unsigned long flags; const char *typeIdent; }; struct _swift_field { unsigned long flags; union { struct _swift_type *typeInfo; Class objcClass; }; void *unknown; struct _swift_field *conditional; union { struct _swift_class *swiftClass; struct _swift_field *subType; }; struct _swift_field *extraType; }; struct _swift_data { unsigned long flags; const char *className; int fieldcount, flasg2; const char *ivarNames; struct _swift_field **(*get_field_data)(); }; struct _swift_class { union { Class meta; unsigned long flags; }; Class supr; void *buckets, *vtable, *pdata; int size, tos, mds, eight; struct _swift_data *swiftData; }; static const char *typeInfoForName( const char *name ) { return strdup([[NSString stringWithFormat:@"@\"%s\"", name] UTF8String]); } static const char *typeInfoForClass( Class aClass ) { return typeInfoForName( class_getName(aClass) ); } static const char *ivar_getTypeEncodingSwift( Ivar ivar, Class aClass ) { struct _swift_class *swiftClass = (__bridge struct _swift_class *)aClass; if ( !((unsigned long)swiftClass->pdata & 0x1) ) return ivar_getTypeEncoding( ivar ); struct _swift_data *swiftData = swiftClass->swiftData; const char *nameptr = swiftData->ivarNames; const char *name = ivar_getName(ivar); int ivarIndex; for ( ivarIndex=0 ; ivarIndexfieldcount ; ivarIndex++ ) if ( strcmp(name,nameptr) == 0 ) break; else nameptr += strlen(nameptr)+1; if ( ivarIndex == swiftData->fieldcount ) return NULL; struct _swift_field **swiftFields = swiftData->get_field_data(); struct _swift_field *field = swiftFields[ivarIndex]; struct _swift_class *ivarClass = field->swiftClass; // this could probably be tidied up if I knew what was going on... if ( field->flags == 0x2 && (field->conditional->flags > 0x2 || (ivarClass && ivarClass->flags>0x2) ) ) return typeInfoForName(field->typeInfo->typeIdent); else if ( field->flags == 0xe ) return typeInfoForClass(field->objcClass); else if ( field->conditional && field->conditional->flagsconditional->flags == 0xe ) return typeInfoForClass(field->conditional->objcClass); else return field->conditional->typeInfo->typeIdent+1; } else if ( !ivarClass ) return field->typeInfo->typeIdent+1; else if ( ivarClass->flags == 0x1 ) return field->subType->typeInfo->typeIdent+1; else if ( ivarClass->flags == 0xe ) return typeInfoForClass(field->subType->objcClass); else return typeInfoForClass((__bridge Class)ivarClass); }
2 Comments
Hey Erica, just wanted to let you know the code doesn’t compile as it is. `ivarIndexfieldcount` is not defined and there’s an extra `}` somewhere in those chained `if – else` Cheers!
The post is from June 2014. I think there’s a 2-week statute of limitations with Swift in terms of language changes.