Просмотр исходного кода

Add details to metadata for class views

Tanner Bennett лет назад: 6
Родитель
Сommit
2541c89b99

+ 11 - 4
Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.m

@@ -54,9 +54,13 @@
 }
 
 - (NSString *)previewWithTarget:(id)object {
-    return [FLEXRuntimeUtility
-        summaryForObject:[self currentValueWithTarget:object]
-    ];
+    if (object_isClass(object) && !self.isClassProperty) {
+        return self.attributes.fullDeclaration;
+    } else {
+        return [FLEXRuntimeUtility
+            summaryForObject:[self currentValueWithTarget:object]
+        ];
+    }
 }
 
 - (UIViewController *)viewerWithTarget:(id)object {
@@ -120,6 +124,9 @@
 }
 
 - (NSString *)previewWithTarget:(id)object {
+    if (object_isClass(object)) {
+        return self.details;
+    }
     return [FLEXRuntimeUtility
         summaryForObject:[self currentValueWithTarget:object]
     ];
@@ -180,7 +187,7 @@
 }
 
 - (NSString *)previewWithTarget:(id)object {
-    return self.selectorString;
+    return [self.selectorString stringByAppendingFormat:@"  —  %@", self.typeEncoding];
 }
 
 - (UIViewController *)viewerWithTarget:(id)object {

+ 2 - 0
Classes/Utility/Runtime/FLEXIvar.h

@@ -28,6 +28,8 @@
 @property (nonatomic, readonly) NSString         *typeEncoding;
 /// The offset of the instance variable.
 @property (nonatomic, readonly) NSInteger        offset;
+/// Describes the type encoding, size, offset, and objc_ivar
+@property (nonatomic, readonly) NSString        *details;
 
 /// For internal use
 @property (nonatomic) id tag;

+ 9 - 0
Classes/Utility/Runtime/FLEXIvar.m

@@ -69,6 +69,15 @@
     _typeEncoding = @(ivar_getTypeEncoding(self.objc_ivar));
     _type         = (FLEXTypeEncoding)[_typeEncoding characterAtIndex:0];
     _offset       = ivar_getOffset(self.objc_ivar);
+
+    NSUInteger size = 0;
+    @try {
+        NSGetSizeAndAlignment(_typeEncoding.UTF8String, &size, nil);
+    } @catch (NSException *exception) { }
+    _details = [NSString stringWithFormat:
+        @"%@ bytes, offset %@  —  %@",
+        (size ? @(size) : @"?"), @(_offset), _typeEncoding
+    ];
 }
 
 - (id)getValue:(id)target {

+ 3 - 1
Classes/Utility/Runtime/FLEXPropertyAttributes.h

@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
 // These are necessary for the mutable subclass to function
 @protected
     NSUInteger _count;
-    NSString *_string, *_backingIvar, *_typeEncoding, *_oldTypeEncoding;
+    NSString *_string, *_backingIvar, *_typeEncoding, *_oldTypeEncoding, *_fullDeclaration;
     NSDictionary *_dictionary;
     objc_property_attribute_t *_list;
     SEL _customGetter, _customSetter;
@@ -43,6 +43,8 @@ NS_ASSUME_NONNULL_BEGIN
 @property (nonatomic, readonly) objc_property_attribute_t *list;
 /// The string value of the property attributes.
 @property (nonatomic, readonly) NSString *string;
+/// A human-readable version of the property attributes.
+@property (nonatomic, readonly) NSString *fullDeclaration;
 /// A dictionary of the property attributes.
 /// Values are either a string or \c @YES. Boolean attributes
 /// which are false will not be present in the dictionary.

+ 51 - 1
Classes/Utility/Runtime/FLEXPropertyAttributes.m

@@ -30,6 +30,8 @@
 @property (nonatomic) BOOL isWeak;
 @property (nonatomic) BOOL isGarbageCollectable;
 
+- (NSString *)buildFullDeclaration;
+
 @end
 
 @implementation FLEXPropertyAttributes
@@ -64,6 +66,8 @@
         _isNonatomic          = attributes[kFLEXPropertyAttributeKeyNonAtomic] != nil;
         _isWeak               = attributes[kFLEXPropertyAttributeKeyWeak] != nil;
         _isGarbageCollectable = attributes[kFLEXPropertyAttributeKeyGarbageCollectable] != nil;
+
+        _fullDeclaration = [self buildFullDeclaration];
     }
     
     return self;
@@ -186,6 +190,42 @@
     return _list;
 }
 
+- (NSString *)buildFullDeclaration {
+    NSMutableString *decl = [NSMutableString new];
+
+    [decl appendFormat:@"%@, ", _isNonatomic ? @"nonatomic" : @"atomic"];
+    [decl appendFormat:@"%@, ", _isReadOnly ? @"readonly" : @"readwrite"];
+
+    BOOL noExplicitMemorySemantics = YES;
+    if (_isCopy) { noExplicitMemorySemantics = NO;
+        [decl appendString:@"copy, "];
+    }
+    if (_isRetained) { noExplicitMemorySemantics = NO;
+        [decl appendString:@"strong, "];
+    }
+    if (_isWeak) { noExplicitMemorySemantics = NO;
+        [decl appendString:@"weak, "];
+    }
+
+    if ([_typeEncoding hasPrefix:@"@"] && noExplicitMemorySemantics) {
+        // *probably* strong if this is an object; strong is the default.
+        [decl appendString:@"strong, "];
+    } else if (noExplicitMemorySemantics) {
+        // *probably* assign if this is not an object
+        [decl appendString:@"assign, "];
+    }
+
+    if (_customGetter) {
+        [decl appendFormat:@"getter=%@, ", NSStringFromSelector(_customGetter)];
+    }
+    if (_customSetter) {
+        [decl appendFormat:@"setter=%@, ", NSStringFromSelector(_customSetter)];
+    }
+
+    [decl deleteCharactersInRange:NSMakeRange(decl.length-2, 2)];
+    return decl.copy;
+}
+
 - (void)dealloc {
     if (_list) {
         free(_list);
@@ -214,12 +254,13 @@
 @property (nonatomic) BOOL stringDelta;
 @property (nonatomic) BOOL dictDelta;
 @property (nonatomic) BOOL listDelta;
+@property (nonatomic) BOOL declDelta;
 @end
 
 #define PropertyWithDeltaFlag(type, name, Name) @dynamic name; \
 - (void)set ## Name:(type)name { \
     if (name != _ ## name) { \
-        _countDelta = _stringDelta = _dictDelta = _listDelta = YES; \
+        _countDelta = _stringDelta = _dictDelta = _listDelta = _declDelta = YES; \
         _ ## name = name; \
     } \
 }
@@ -313,4 +354,13 @@ PropertyWithDeltaFlag(BOOL, isGarbageCollectable, IsGarbageCollectable);
     return _dictionary;
 }
 
+- (NSString *)fullDeclaration {
+    if (self.declDelta || !_fullDeclaration) {
+        _declDelta = NO;
+        _fullDeclaration = [self buildFullDeclaration];
+    }
+
+    return _fullDeclaration;
+}
+
 @end