[英]Objective-C: How to get properties of an object inside NSMutableArray?
[英]Get an object properties list in Objective-C
如何在Objective-C中獲得給定對象屬性的列表(以NSArray
或NSDictionary
的形式)?
設想以下情形:我定義了一個父類,該類僅擴展了NSObject
,該類包含一個NSString
,一個BOOL
和一個NSData
對象作為屬性。 然后,我有幾個擴展該父類的類,每個類都添加了許多不同的屬性。
我有什么辦法可以在父類上實現遍歷整個對象並返回例如每個(子)類屬性的NSArray
作為不在父類上的NSStrings
的實例方法,因此我以后可以將這些NSString
用於KVC?
我只是設法自己得到答案。 通過使用Obj-C運行時庫,我可以按自己的方式訪問屬性:
- (void)myMethod {
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithCString:propName
encoding:[NSString defaultCStringEncoding]];
NSString *propertyType = [NSString stringWithCString:propType
encoding:[NSString defaultCStringEncoding]];
...
}
}
free(properties);
}
這需要我創建一個“ getPropertyType” C函數,該函數主要取自Apple代碼示例(目前不記得確切的源代碼):
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T') {
if (strlen(attribute) <= 4) {
break;
}
return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
}
}
return "@";
}
@boliva的答案很好,但是需要一些額外的處理原語,例如int,long,float,double等。
我以他為基礎來添加此功能。
// PropertyUtil.h
#import
@interface PropertyUtil : NSObject
+ (NSDictionary *)classPropsFor:(Class)klass;
@end
// PropertyUtil.m
#import "PropertyUtil.h"
#import "objc/runtime.h"
@implementation PropertyUtil
static const char * getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
printf("attributes=%s\n", attributes);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T' && attribute[1] != '@') {
// it's a C primitive type:
/*
if you want a list of what will be returned for these primitives, search online for
"objective-c" "Property Attribute Description Examples"
apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
*/
return (const char *)[[NSData dataWithBytes:(attribute + 1) length:strlen(attribute) - 1] bytes];
}
else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
// it's an ObjC id type:
return "id";
}
else if (attribute[0] == 'T' && attribute[1] == '@') {
// it's another ObjC object type:
return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
}
}
return "";
}
+ (NSDictionary *)classPropsFor:(Class)klass
{
if (klass == NULL) {
return nil;
}
NSMutableDictionary *results = [[[NSMutableDictionary alloc] init] autorelease];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(klass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
[results setObject:propertyType forKey:propertyName];
}
}
free(properties);
// returning a copy here to make sure the dictionary is immutable
return [NSDictionary dictionaryWithDictionary:results];
}
@end
@ orange80的答案有一個問題:實際上,它並不總是以0終止字符串。 這可能會導致意外的結果,例如在嘗試將其轉換為UTF8時崩潰(我確實有一個非常煩人的崩潰錯誤,正因為如此。調試它很有趣^^)。 我實際上是通過從屬性獲取NSString,然后調用cStringUsingEncoding:來修復它的。 現在,它就像是一種魅力。 (也與ARC合作,至少對我而言)
所以這是我現在的代碼版本:
// PropertyUtil.h
#import
@interface PropertyUtil : NSObject
+ (NSDictionary *)classPropsFor:(Class)klass;
@end
// PropertyUtil.m
#import "PropertyUtil.h"
#import <objc/runtime.h>
@implementation PropertyUtil
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
//printf("attributes=%s\n", attributes);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T' && attribute[1] != '@') {
// it's a C primitive type:
/*
if you want a list of what will be returned for these primitives, search online for
"objective-c" "Property Attribute Description Examples"
apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
*/
NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
// it's an ObjC id type:
return "id";
}
else if (attribute[0] == 'T' && attribute[1] == '@') {
// it's another ObjC object type:
NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
}
return "";
}
+ (NSDictionary *)classPropsFor:(Class)klass
{
if (klass == NULL) {
return nil;
}
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(klass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
[results setObject:propertyType forKey:propertyName];
}
}
free(properties);
// returning a copy here to make sure the dictionary is immutable
return [NSDictionary dictionaryWithDictionary:results];
}
@end
當我嘗試使用iOS 3.2時,getPropertyType函數不能很好地與屬性描述配合使用。 我從iOS文檔中找到了一個示例:“ Objective-C運行時編程指南:聲明的屬性”。
這是iOS 3.2中屬性列表的修訂代碼:
#import <objc/runtime.h>
#import <Foundation/Foundation.h>
...
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([UITouch class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}
free(properties);
我發現boliva的解決方案在模擬器中可以正常工作,但是在設備上固定長度的子字符串會引起問題。 我針對此問題寫了一個更符合Objective-C要求的解決方案,該解決方案可在設備上運行。 在我的版本中,我將屬性的C-String轉換為NSString並對其執行字符串操作以獲得僅具有類型描述的子字符串。
/*
* @returns A string describing the type of the property
*/
+ (NSString *)propertyTypeStringOfProperty:(objc_property_t) property {
const char *attr = property_getAttributes(property);
NSString *const attributes = [NSString stringWithCString:attr encoding:NSUTF8StringEncoding];
NSRange const typeRangeStart = [attributes rangeOfString:@"T@\""]; // start of type string
if (typeRangeStart.location != NSNotFound) {
NSString *const typeStringWithQuote = [attributes substringFromIndex:typeRangeStart.location + typeRangeStart.length];
NSRange const typeRangeEnd = [typeStringWithQuote rangeOfString:@"\""]; // end of type string
if (typeRangeEnd.location != NSNotFound) {
NSString *const typeString = [typeStringWithQuote substringToIndex:typeRangeEnd.location];
return typeString;
}
}
return nil;
}
/**
* @returns (NSString) Dictionary of property name --> type
*/
+ (NSDictionary *)propertyTypeDictionaryOfClass:(Class)klass {
NSMutableDictionary *propertyMap = [NSMutableDictionary dictionary];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(klass, &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
NSString *propertyName = [NSString stringWithCString:propName encoding:NSUTF8StringEncoding];
NSString *propertyType = [self propertyTypeStringOfProperty:property];
[propertyMap setValue:propertyType forKey:propertyName];
}
}
free(properties);
return propertyMap;
}
此實現適用於Objective-C對象類型和C原語。 它與iOS 8兼容。 此類提供了三種方法:
+ (NSDictionary *) propertiesOfObject:(id)object;
返回對象的所有可見屬性的字典,包括其所有超類的屬性。
+ (NSDictionary *) propertiesOfClass:(Class)class;
返回一個類的所有可見屬性的字典,包括其所有超類的屬性。
+ (NSDictionary *) propertiesOfSubclass:(Class)class;
返回特定於子類的所有可見屬性的字典。 不包括其超類的屬性。
使用這些方法的一個有用示例是將對象復制到Objective-C中的子類實例,而不必在copy方法中指定屬性 。 該答案的某些部分基於該問題的其他答案,但它為所需功能提供了更簡潔的界面。
標頭:
// SYNUtilities.h
#import <Foundation/Foundation.h>
@interface SYNUtilities : NSObject
+ (NSDictionary *) propertiesOfObject:(id)object;
+ (NSDictionary *) propertiesOfClass:(Class)class;
+ (NSDictionary *) propertiesOfSubclass:(Class)class;
@end
實現方式:
// SYNUtilities.m
#import "SYNUtilities.h"
#import <objc/objc-runtime.h>
@implementation SYNUtilities
+ (NSDictionary *) propertiesOfObject:(id)object
{
Class class = [object class];
return [self propertiesOfClass:class];
}
+ (NSDictionary *) propertiesOfClass:(Class)class
{
NSMutableDictionary * properties = [NSMutableDictionary dictionary];
[self propertiesForHierarchyOfClass:class onDictionary:properties];
return [NSDictionary dictionaryWithDictionary:properties];
}
+ (NSDictionary *) propertiesOfSubclass:(Class)class
{
if (class == NULL) {
return nil;
}
NSMutableDictionary *properties = [NSMutableDictionary dictionary];
return [self propertiesForSubclass:class onDictionary:properties];
}
+ (NSMutableDictionary *)propertiesForHierarchyOfClass:(Class)class onDictionary:(NSMutableDictionary *)properties
{
if (class == NULL) {
return nil;
}
if (class == [NSObject class]) {
// On reaching the NSObject base class, return all properties collected.
return properties;
}
// Collect properties from the current class.
[self propertiesForSubclass:class onDictionary:properties];
// Collect properties from the superclass.
return [self propertiesForHierarchyOfClass:[class superclass] onDictionary:properties];
}
+ (NSMutableDictionary *) propertiesForSubclass:(Class)class onDictionary:(NSMutableDictionary *)properties
{
unsigned int outCount, i;
objc_property_t *objcProperties = class_copyPropertyList(class, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = objcProperties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
[properties setObject:propertyType forKey:propertyName];
}
}
free(objcProperties);
return properties;
}
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T' && attribute[1] != '@') {
// A C primitive type:
/*
For example, int "i", long "l", unsigned "I", struct.
Apple docs list plenty of examples of values returned. For a list
of what will be returned for these primitives, search online for
"Objective-c" "Property Attribute Description Examples"
*/
NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
// An Objective C id type:
return "id";
}
else if (attribute[0] == 'T' && attribute[1] == '@') {
// Another Objective C id type:
NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
}
return "";
}
@end
如果有人需要很好地獲取從父類繼承的屬性 (如我所做的那樣),則可以對“ orange80 ”代碼進行一些修改以使其遞歸:
+ (NSDictionary *)classPropsForClassHierarchy:(Class)klass onDictionary:(NSMutableDictionary *)results
{
if (klass == NULL) {
return nil;
}
//stop if we reach the NSObject class as is the base class
if (klass == [NSObject class]) {
return [NSDictionary dictionaryWithDictionary:results];
}
else{
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(klass, &outCount);
for (i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
NSString *propertyType = [NSString stringWithUTF8String:propType];
[results setObject:propertyType forKey:propertyName];
}
}
free(properties);
//go for the superclass
return [PropertyUtil classPropsForClassHierarchy:[klass superclass] onDictionary:results];
}
}
“屬性”一詞有點模糊。 您是說看起來像訪問器的實例變量,屬性,方法嗎?
這三個問題的答案都是“是的,但這不是很容易”。 Objective-C運行時API包括用於獲取類的ivar列表,方法列表或屬性列表的函數(例如, class_copyPropertyList()
),然后包括每種類型的對應函數,以獲取列表中項目的名稱(例如, , property_getName()
)。
總而言之,要想正確使用它可能需要做很多工作,或者至少比大多數人想要做的要多得多,因為通常這只是一個瑣碎的功能。
另外,您可以編寫一個Ruby / Python腳本,該腳本僅讀取頭文件並查找該類的“屬性”。
我能夠得到@ orange80的答案,以便與ARC ENABLED一起工作…………我想要的-至少……但並非沒有嘗試和錯誤。 希望這些附加信息可以使某人免於悲痛。
將他在answer =中描述的那些類保存為類,並在您的AppDelegate.h
(或任何其他內容)中,放入#import PropertyUtil.h
。 那你的...
- (void)applicationDidFinishLaunching:
(NSNotification *)aNotification {
方法(或其他方法) …
PropertyUtil *props = [PropertyUtil new];
NSDictionary *propsD = [PropertyUtil classPropsFor:
(NSObject*)[gist class]];
NSLog(@"%@, %@", props, propsD);
…
秘訣是將您要查詢的類的實例變量( 在本例中,我的類是Gist
,而我的Gist
實例是gist
) Gist
為 ... 到NSObject … (id)
等,不會被剪切..出於各種奇怪而深奧的原因。 這樣將為您提供一些輸出,如…
<PropertyUtil: 0x7ff0ea92fd90>, {
apiURL = NSURL;
createdAt = NSDate;
files = NSArray;
gistDescription = NSString;
gistId = NSString;
gitPullURL = NSURL;
gitPushURL = NSURL;
htmlURL = NSURL;
isFork = c;
isPublic = c;
numberOfComments = Q;
updatedAt = NSDate;
userLogin = NSString;
}
對於蘋果公司一直以來對ObjC的“驚奇”自省的自誇/強迫症患者,他們肯定不會輕易地以這種“眼神”來表現這種簡單的“表情”。
如果您真的想狂野地走..退房.. class-dump ,這是一種令人難以置信的瘋狂方法,可以窺視任何可執行文件的類頭 ,等等。。。它為您的類提供了VERBOSE外觀……我,就個人而言,在很多情況下都可以找到真正有用的方法。 實際上,這就是為什么我開始尋求OP的問題的解決方案的原因。 這里是一些使用參數..享受!
-a show instance variable offsets
-A show implementation addresses
--arch <arch> choose a specific architecture from a universal binary (ppc, ppc64, i386, x86_64)
-C <regex> only display classes matching regular expression
-f <str> find string in method name
-I sort classes, categories, and protocols by inheritance (overrides -s)
-r recursively expand frameworks and fixed VM shared libraries
-s sort classes and categories by name
-S sort methods by name
我使用的是提供的功能boliva,但顯然它已停止與iOS 7一起使用。因此,現在可以使用以下方法代替靜態const char * getPropertyType(objc_property_t屬性):
- (NSString*) classOfProperty:(NSString*)propName{
objc_property_t prop = class_getProperty([self class], [propName UTF8String]);
if (!prop) {
// doesn't exist for object
return nil;
}
const char * propAttr = property_getAttributes(prop);
NSString *propString = [NSString stringWithUTF8String:propAttr];
NSArray *attrArray = [propString componentsSeparatedByString:@","];
NSString *class=[attrArray objectAtIndex:0];
return [[class stringByReplacingOccurrencesOfString:@"\"" withString:@""] stringByReplacingOccurrencesOfString:@"T@" withString:@""];
}
你有三個魔法
Ivar* ivars = class_copyIvarList(clazz, &count); // to get all iVars
objc_property_t *properties = class_copyPropertyList(clazz, &count); //to get all properties of a class
Method* methods = class_copyMethodList(clazz, &count); // to get all methods of a class.
以下代碼段可以為您提供幫助。
-(void) displayClassInfo
{
Class clazz = [self class];
u_int count;
Ivar* ivars = class_copyIvarList(clazz, &count);
NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* ivarName = ivar_getName(ivars[i]);
ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]];
}
free(ivars);
objc_property_t* properties = class_copyPropertyList(clazz, &count);
NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* propertyName = property_getName(properties[i]);
[propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
}
free(properties);
Method* methods = class_copyMethodList(clazz, &count);
NSMutableArray* methodArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
SEL selector = method_getName(methods[i]);
const char* methodName = sel_getName(selector);
[methodArray addObject:[NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]];
}
free(methods);
NSDictionary* classInfo = [NSDictionary dictionaryWithObjectsAndKeys:
ivarArray, @"ivars",
propertyArray, @"properties",
methodArray, @"methods",
nil];
NSLog(@"%@", classInfo);
}
這些答案很有幫助,但是我需要更多的答案。 我要做的就是檢查屬性的類類型是否等於現有對象的類類型。 上面的所有代碼均無法執行此操作,因為:為了獲取對象的類名,object_getClassName()返回如下文本:
__NSArrayI (for an NSArray instance)
__NSArrayM (for an NSMutableArray instance)
__NSCFBoolean (an NSNumber object initialized by initWithBool:)
__NSCFNumber (an NSValue object initialized by [NSNumber initWithBool:])
但是,如果從上述示例代碼中調用getPropertyType(...),則將這樣定義的類的屬性的4個objc_property_t結構構造為:
@property (nonatomic, strong) NSArray* a0;
@property (nonatomic, strong) NSArray* a1;
@property (nonatomic, copy) NSNumber* n0;
@property (nonatomic, copy) NSValue* n1;
它分別返回字符串,如下所示:
NSArray
NSArray
NSNumber
NSValue
因此,無法確定NSObject是否能夠作為該類的一個屬性的值。 那怎么辦呢?
這是我的完整示例代碼(函數getPropertyType(...)與上面相同):
#import <objc/runtime.h>
@interface FOO : NSObject
@property (nonatomic, strong) NSArray* a0;
@property (nonatomic, strong) NSArray* a1;
@property (nonatomic, copy) NSNumber* n0;
@property (nonatomic, copy) NSValue* n1;
@end
@implementation FOO
@synthesize a0;
@synthesize a1;
@synthesize n0;
@synthesize n1;
@end
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
//printf("attributes=%s\n", attributes);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T' && attribute[1] != '@') {
// it's a C primitive type:
// if you want a list of what will be returned for these primitives, search online for
// "objective-c" "Property Attribute Description Examples"
// apple docs list plenty of examples of what you get for int "i", long "l", unsigned "I", struct, etc.
NSString *name = [[NSString alloc] initWithBytes:attribute + 1 length:strlen(attribute) - 1 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
else if (attribute[0] == 'T' && attribute[1] == '@' && strlen(attribute) == 2) {
// it's an ObjC id type:
return "id";
}
else if (attribute[0] == 'T' && attribute[1] == '@') {
// it's another ObjC object type:
NSString *name = [[NSString alloc] initWithBytes:attribute + 3 length:strlen(attribute) - 4 encoding:NSASCIIStringEncoding];
return (const char *)[name cStringUsingEncoding:NSASCIIStringEncoding];
}
}
return "";
}
int main(int argc, char * argv[]) {
NSArray* a0 = [[NSArray alloc] init];
NSMutableArray* a1 = [[NSMutableArray alloc] init];
NSNumber* n0 = [[NSNumber alloc] initWithBool:YES];
NSValue* n1 = [[NSNumber alloc] initWithBool:NO];
const char* type0 = object_getClassName(a0);
const char* type1 = object_getClassName(a1);
const char* type2 = object_getClassName(n0);
const char* type3 = object_getClassName(n1);
objc_property_t property0 = class_getProperty(FOO.class, "a0");
objc_property_t property1 = class_getProperty(FOO.class, "a1");
objc_property_t property2 = class_getProperty(FOO.class, "n0");
objc_property_t property3 = class_getProperty(FOO.class, "n1");
const char * memberthype0 = getPropertyType(property0);//property_getAttributes(property0);
const char * memberthype1 = getPropertyType(property1);//property_getAttributes(property1);
const char * memberthype2 = getPropertyType(property2);//property_getAttributes(property0);
const char * memberthype3 = getPropertyType(property3);//property_getAttributes(property1);
NSLog(@"%s", type0);
NSLog(@"%s", type1);
NSLog(@"%s", type2);
NSLog(@"%s", type3);
NSLog(@"%s", memberthype0);
NSLog(@"%s", memberthype1);
NSLog(@"%s", memberthype2);
NSLog(@"%s", memberthype3);
return 0;
}
對於Swift圍觀者,您可以通過使用Encodable
功能來獲得此功能。 我將解釋如何:
使您的對象符合可Encodable
協議
class ExampleObj: NSObject, Encodable { var prop1: String = "" var prop2: String = "" }
為Encodable
創建擴展以提供toDictionary
功能
public func toDictionary() -> [String: AnyObject]? { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted guard let data = try? encoder.encode(self), let json = try? JSONSerialization.jsonObject(with: data, options: .init(rawValue: 0)), let jsonDict = json as? [String: AnyObject] else { return nil } return jsonDict }
在對象實例和訪問keys
屬性上調用toDictionary
。
let exampleObj = ExampleObj() exampleObj.toDictionary()?.keys
瞧! 像這樣訪問您的屬性:
for k in exampleObj!.keys { print(k) } // Prints "prop1" // Prints "prop2"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.