On Feb 1, 2013, at 02:21 , Graham Cox <graham....@bigpond.com> wrote:
> Well, I might pursue this line of thought if I had a clear understanding of > how to reliably check the type of an arbitrary property. Here are some fragments of the code I use to analyze properties. Note that this is accessing @property information, not general method information: > // Get a dictionary whose keys are the first character of each substring > of a property attribute string, > // and whose objects are the corresponding rest of each substring > > + (NSDictionary*) propertyAttributesForPropertyName: (NSString*) name > forOwningClass: (Class) owningClass > { > NSMutableDictionary* result = [NSMutableDictionary dictionary]; > > // Find the attribute string, if the property is defined > > const char* classPropertyName = [name cStringUsingEncoding: > NSASCIIStringEncoding]; > NSAssert (classPropertyName, [NSString stringWithFormat: @"Invalid > characters in property name %@ of class %@", name, NSStringFromClass > (owningClass)]); > > objc_property_t classProperty = class_getProperty (owningClass, > classPropertyName); > if (!classProperty) > return result; > > NSString* attributes = [NSString stringWithCString: > property_getAttributes (classProperty) encoding: NSASCIIStringEncoding]; > if (!attributes) > return nil; > > // Divide the string into substrings > > NSArray* components = [attributes componentsSeparatedByString: @","]; > for (NSString* component in components) > { > NSRange range = [component > rangeOfComposedCharacterSequenceAtIndex: 0]; > if (!range.length) > continue; > > NSString* componentCharacter = [component substringWithRange: > range]; > NSString* restOfComponent = [component substringFromIndex: > range.location + range.length]; > if (!componentCharacter || !componentCharacter.length || > !restOfComponent) > return nil; > > NSAssert (![result objectForKey: componentCharacter], @"Invalid > property attribute string"); > > [result setObject: restOfComponent forKey: componentCharacter]; > } > > return result; > } Use the above to get some useful information about the property: > NSString* typeEncoding = [propertyAttributes objectForKey: @"T"]; > if (!typeEncoding || [typeEncoding isEqualToString: @""]) > return YES; > > BOOL isReadOnly = !![propertyAttributes objectForKey: @"R"]; > BOOL isCopy = !![propertyAttributes objectForKey: @"C"]; Examine the property type: > // Get the type character for a non-struct type > > if ([typeEncoding characterAtIndex: 0] != '{') > propertyEncodedType = [typeEncoding substringToIndex: 1]; > > // Or get the type string for a struct type > > else > { > // Ignore the property if the type encoding is not of the > form '{' <non-null-struct-tag-name> '=' > > NSRange range = [typeEncoding rangeOfString: @"="]; > if (!range.length) > return YES; > > if (range.location < 2) > return YES; > > // Take everything up to and including to the '=' > > NSString* structEncoding = [typeEncoding substringToIndex: > range.location + range.length]; > > // Look for a structure that we recognize > > NSString* pointTypeString = [NSString stringWithCString: > @encode (CGPoint) encoding: NSASCIIStringEncoding]; > > if ([pointTypeString hasPrefix: structEncoding]) > propertyEncodedType = pointTypeString; > … > } You might be interested in a different subset of property types, but this shows at least part of the way to get there. _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com