Giter Site home page Giter Site logo

jrdb's Introduction

iOS用对FMDB封装

一个对FMDB进行类Hibernate封装的ios库

Build Status Pod Version Pod Platform Pod License

GitHub: sucbers

Feedback: [email protected]

有问题或者bug欢迎随时issues我,或者邮件。感谢使用

2.0更新

  • 数据库字段名,从默认的_ivar名 改为 property名 : _name -> name
  • 数据库操作对象获取改为连接池: [JRDBMgr defaultDB] -> [JRDBMgr shareInstance].getHandler
  • 抛弃缓存功能
  • 新增And, Or查询语句

描述(Description)

  • 使用分类的模式,模仿Hibernate,对FMDB进行简易封装
  • 使用协议,不用继承基类,对任意NSObject可以进行入库操作
  • Objective-C(Swift 请移步 Swift扩展

目录(Index)

安装(Installation)

pod 'JRDB'

开始(Start)

JRDBMgr 使用

设置数据库路径

[[JRDBMgr shareInstance] setDefaultDatabasePath:@"/Users/mac/Desktop/test11.sqlite"];

是否打印sql语句

[JRDBMgr shareInstance].debugMode = YES;

获取处理器

  • 从连接池中获取数据库处理器
[[JRDBMgr shareInstance] getHandler]; 

关闭数据库

[[JRDBMgr shareInstance] close]; 

注册

  • 需要使用本库的类都需要注册。
[[JRDBMgr shareInstance] registerClazzes:@[
                                           [Person class],
                                           ]];

表名

默认类名为表明,可以自定义表名,在主类中重写一下方法即可

+ (NSString *)jr_customTableName {
    return @"my_tableName";
}

主键

默认每个对象入库都会持有一个ID [person ID] , 作为数据库的主键,库通过这个 ID 来识别对象是否与数据库关联,所以不是必要时,不要操作此属性

自定义主键

不同的业务需求,有可能使用的主键有特定的业务意义,需要自行定义。

在需要自定义的实体类中实现一下方法

/// 自定义主键的对应的属性 (需要是属性的全名)
+ (NSString *)jr_customPrimarykey {
    return @"name"; // 对应property的属性名
}
/// 自定义主键属性值
- (id)jr_customPrimarykeyValue {
    return self.name;
}

通过下面的方法可以获取对应的值

/**
 *  如果有自定义主键,则返回自定义主键key,例如 name,若没有实现,则返回默认主键key : @"_ID"
 */
[Person jr_primaryKey];

/**
 * 如果有自定义主键,则返回自定义主键的值,如果没有,则返回 [self ID]
 */
[p jr_primaryKeyValue];

自定义字段名

默认使用Property的属性名进行字段名定义,可以对每个地段进行自定义数据库字段名,在主类中重写以下方法即可

  • 无返回字段默认使用property属性名当做数据库列名
+ (NSDictionary<NSString *,NSString *> *)jr_databaseNameMap {
    return @{
             @"name" : @"db_name",
             @"age" : @"db_age",
             @"height" : @"db_height",
             };
}

忽略字段

默认非数据库基本类型都会忽略不入库。

数据库基本类型:

  • NSString
  • NSDate
  • NSData
  • int, unsigned int, double, float, long.....

非以上类型都会自动忽略不入库。

若有特定需要忽略字段,需要实现一下方法

/// 忽略age属性,不做入库操作
+ (NSArray *)jr_excludePropertyNames {
    return @[
             @"age",
             ];
}

表操作(TableOperation)

建表

J_CreateTable(Person)

更新表

  • 更新表时只会添加字段,不会删除或更新字段名,有需要的话需要自行写sql语句解决

J_UpdateTable(Person)

删除表

J_DropTable(Person)

重建表

J_TruncateTable(Person)


保存(Save)

    
BOOL result = J_Insert(p)
					.InDB([JRDBMgr shareInstance].getHandler) // by Default
					.Recursive(NO)  		       // by default
					.Sync(YES)			       // by default
					.Transaction(YES)	       // by default
					.updateResult;             // 执行
    
// 可以省略为
BOOL result = J_Insert(p).updateResult;
    
// 数组保存,两种 api 自由使用
BOOL result = J_Insert(p1, p2, p3).updateResult;
    
BOOL result = J_Insert(@[p1, p2, p3]).updateResult;

更新 (Update)

更新操作需要提供对象的主键,请确保需要更新的对象都是从数据库查出来的;(也可以手动设置主键让库识别,不建议)

BOOL result = J_Update(p)
					.Columns(@[@"age", @"name"])  // 更新指定列
				//	.Ignore(@[@"age", @"name"])   // 忽略指定列
					.InDB([JRDBMgr shareInstance].getHandler)      // by default
					.Recursive(NO)                  // by default
					.Sync(YES)                      // by default
					.Transaction(YES)               // by default
					.updateResult;                  // 执行
					
BOOL result = J_Update(p).Ignore(@[@"phone"]).updateResult;

// 更新数组
BOOL result = J_Update(p1, p2).updateResult;
BOOL result = J_Update(@[p1, p2, p3]).updateResult;

删除(Delete)

删除操作需要提供对象的主键,请确保需要更新的对象都是从数据库查出来的;(也可以手动设置主键让库识别,不建议)

// 删除
BOOL result = J_Delete(p)
					.InDB([JRDBMgr shareInstance].getHandler)      // by default
					.Recursive(NO)                  // by default
					.Sync(YES)                      // by default
					.Transaction(YES)               // by default
					.updateResult;                  // 执行

查询(Query)

// 条件查询

// And Or 对应Property中的属性名

NSArray<Person *> = J_Select(Person) // select * from person [where 1=1]
						.And(@"age").lt(@10) // and age < 10
						.Or(@"height").gt(@120) // or height > 120
						.Or(@"name").like(@"Wang%") // or name like 'Wang%'
						.And(@"weight").nq(@200) // and weight <> 200
						.list

// 普通查询
NSArray<Person *> *result =
				    J_Select(Person)    // 指定查询对象
				    .Recursive(YES)		// 默认 可省略
				    .Sync(YES)			// 默认 可省略
				    .Desc(NO)           // 默认 可省略
				    .Where(@"name like ? and height > ?")  // 对应数据库中的字段名
				    .Params(@[@"L%", @150])                // 对应条件语句的 ? 可省略
				    .Group(@"level")                      // Group 可省略
				    .Order(@"age")                        // Order 可省略
				    .Limit(0, 10)                          // 分页 start, length 可省略
				    .list;

// 自定义查询
NSArray<Person *> *result1 =
						J_SelectColumns(@[@"age", @"name"])
						.From([Person class])
						.Recursive(YES)   // 在自定义查询中不会起作用
						.Sync(YES)		  //  默认 可省略
						.Where(@"name like ? and height > ?") // 对应数据库中的字段名
						.Params(@[@"L%", @150])
						.Group(@"level") // 对应数据库中的字段名
						.Order(@"age") // 对应数据库中的字段名
						.Limit(0, 10)
						.Desc(NO)
						.list;

NSUInteger count =
				J_SelectCount(Person) // 查询哪个类
				.Recursive(YES)   // 在自定义查询中不会起作用
				.Sync(YES)		  //  默认 可省略
				.Where(@"name like ? and height > ?")
				.Params(@[@"L%", @150])
				.Group(@"level")
				.Order(@"age")
				.Limit(0, 10)
				.Desc(NO)
				.count;
                    

链式调用配置(Configuration)

配置 功能 参数类型
InDB [JRDBMgr shareInstance].getHandler by default; id<JRPersistentHandler>
From 自定义查询时指定的类名
or 子查询的Chain对象
Class | JRDBChain *
Recursive NO by default;
NO:效率高,
YES:关联操作效率低
YES or NO
Transaction YES by default;
NO:本操作不包含事务,外界需要事务支持
YES:包含事务
YES or NO
Sync YES by default;
YES:阻塞本线程,线程安全同步执行数据库操作;
NO:在本线程执行数据库操作,线程不安全
YES or NO
Where Where 后面的条件筛选语句,使用 ?作为参数占位符
使用的字段需要与数据库字段相同
NSString *
WhereIdIs 等同于 Where(@" _id = ?") NSString *
WherePKIs 等同于 Where(@"<#primary key#> = ?") id
And And语句,跟着属性名 And(@"name") NSString
Or Or语句,跟着属性名 Or(@"age") NSString
eq eq语句,跟着参数 eq(@10) 相当于SQL语句的 「=」 id
nq nq语句,跟着参数 nq(@10) 相当于SQL语句的 「<>」 id
gt gt语句,跟着参数 eq(@10) 相当于SQL语句的 「>」 id
lt lt语句,跟着参数 eq(@10) 相当于SQL语句的 「<」 id
gtOrEq gtOrEq语句,跟着参数 eq(@10) 相当于SQL语句的 「>=」 id
ltOrEq ltOrEq语句,跟着参数 eq(@10) 相当于SQL语句的 「<=」 id
like like语句,跟着参数 eq(@10) 相当于SQL语句的 「like」 id
Params Where 语句占位符对应的参数 NSArray *
Columns 更新时候指定更新的列 NSArray *
Ignore 更新时指定忽略的列 NSArray *
Group group by 字段 NSString *
Order order by 字段 NSString *
Limit 分页字段 (start, length) unsigned long, unsigned long
Desc NO by default; 是否根据orderby 进行降序 YES or NO

关联操作(Link)

描述:当一个类的一个属性为一个实体类,在操作数据库时,通过配置,也可以进行同时操作

例如:当保存 Person 时,也想同时保存 card 对象, Money数组,以及 children数组, 则可以进行关联操作。需要在对应的类实现一下方法, 并且子对象也需要注册

// 注册子model类 
[[JRDBMgr shareInstance] registerClazzes:@[
                                           [Person class],
                                           [Card class],
                                           [Money class],
                                           ]];



@interface Person : NSObject

@property (nonatomic, strong) Card *card;
@property (nonatomic, strong) NSMutableArray<Money *> *money;
@property (nonatomic, strong) NSMutableArray<Person *> *children;

@end

@implementation

/// 单个对象关联
+ (NSDictionary<NSString *,Class<JRPersistent>> *)jr_singleLinkedPropertyNames {
    return @{
             @"card" : [Card class],
             };
}

/// 数组对象关联
+ (NSDictionary<NSString *,Class<JRPersistent>> *)jr_oneToManyLinkedPropertyNames {
    return @{
             @"money" : [Money class],
             @"children" : [Person class],
             };
}

@end

关联操作 (保存)

Person *p = [Person new];
Card *c = [Card new];
p.card = c;
p.money = @[m1,m2,m3];
p.children = @[p1,p2,p3];

BOOL result = J_Insert(p)
					.Recursive(YES) // 默认为NO, 需要手动指定关联保存
					.updateResult;

关联操作(更新)

注意:若子对象都是没有保存过的(既数据库没有的对象),则全部保存。若有已存在对象,不保存不更新。

  • 出于更新的操作的随意性比较重,更新时不进行一切关联操作,即更新时,只更新本model相关信息,不更新所有子model的信息。当层级较多的时候,需要从子层级开始一步一步开始更新上来(所以不建议建立太多层级)

  • 更新本model的信息包括:

    • 子model的ID会保存(若有)
    • 子model数组的数量(若子model数组数量发生变更会更新,但是子model的数组不会更到数据库)
BOOL result = J_Update(p).Recursive(YES).updateResult;

--

关联操作(删除)

  • 和更新一样,删除时,只会删除本model的信息,不会进行一切关联操作。
  • 删除时,会删除一对多的中间表无用信息
BOOL result = J_Delete(p).Recursive(YES).updateResult;

关联操作(查询)

NSArray<Person *> *list = J_Select(Person).Recursive(YES).list;

宏(Macro)

  • 使用宏,让调用变成更智能
    • From([Person class]) --> FromJ(Person)
    • Where(@"name = ?") --> WhereJ(_name = ?)
    • Order(@"name") --> OrderJ(name)
    • Group(@"name") --> GroupJ(name)
    • Params(@[@"jack", @"mark"]) --> ParamsJ(@"jack", @"mark")
    • Ignore(@[@"name", @"age"]) --> IgnoreJ(@"name", @"age")
    • Columns(@[@"name", @"age"]) --> ColumnsJ(@"name", @"age")
// example
NSArray *result = J_Select(Person)
                    .WhereJ(name like ? and height > ?)
                    .ParamsJ(@"a%", @100)
                    .GroupJ(h_double)
                    .OrderJ(d_long_long)
                    .list;
                    
BOOL result = J_Update(person)
						.ColumnsJ(J(name), J(age))
					//	.IgnoreJ(J(name), J(age))
                    .updateResult;

子查询(SubQuery)

// 正常查询只能先排序再分页,加入子查询,可以先分页,再从子结果中排序 . ie. 

NSArray<Person *> *list =J_Select(Person)
                                .From(
                                    J_Select(Person).Limit(0, 10) // 放入一个子查询,外部查询则从子查询的结果里继续查询
                                ).OrderJ(age)
                                .Descend
                                .list;

NSObject+JRDB

给NSObject添加分类方法,以方便快捷的方式使用本库的渐变功能

- (BOOL)jr_saveOrUpdateOnly;// 非关联操作
- (BOOL)jr_saveOrUpdate;	 // 关联操作

#pragma mark - save

- (BOOL)jr_saveOnly;
- (BOOL)jr_save;

#pragma mark - update

- (BOOL)jr_updateOnlyColumns:(NSArray<NSString *> * _Nullable)columns;
- (BOOL)jr_updateColumns:(NSArray<NSString *> * _Nullable)columns;

- (BOOL)jr_updateOnlyIgnore:(NSArray<NSString *> * _Nullable)Ignore;
- (BOOL)jr_updateIgnore:(NSArray<NSString *> * _Nullable)Ignore;

#pragma mark - delete

+ (BOOL)jr_deleteAllOnly;
+ (BOOL)jr_deleteAll;

- (BOOL)jr_deleteOnly;
- (BOOL)jr_delete;

#pragma mark - select

/// 关联查询
+ (instancetype _Nullable)jr_findByID:(NSString * _Nonnull)ID;
+ (instancetype _Nullable)jr_findByPrimaryKey:(id _Nonnull)primaryKey;
+ (NSArray<id<JRPersistent>> * _Nonnull)jr_findAll;

/// 非关联查询
+ (instancetype _Nullable)jr_getByID:(NSString * _Nonnull)ID;
+ (instancetype _Nullable)jr_getByPrimaryKey:(id _Nonnull)primaryKey;
+ (NSArray<id<JRPersistent>> * _Nonnull)jr_getAll;

线程安全

使用本库的数据库,都是阻塞本线程,并且线程安全的,所有操作带有事务。
操作本库管理的数据库时,请使用本库提供的API进行操作,否则有可能产生数据库锁问题


泛型提示

abc

通过泛型,查询出来后,编译器直接识别结果为对应对象,减少强转操作。


更多使用 请查看 JRPersistentHandler.h

jrdb's People

Contributors

davisjy avatar scubers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jrdb's Issues

主键问题

当我设置jr_customPrimarykey为userId后,发现创建表语句并没有按照预期的进行,JRDB仍然创建了ID字段并设置其为主键。打印语句如下:CREATE TABLE User (_ID text primary key , _name TEXT, _age INTEGER, _birthday TIMESTAMP, _userId INTEGER, _size INTEGER)

自身的一对多关系,保存错误

若AModel具有自身的一对多关系,调用save方法会报错
DB Error: 1 "duplicate column name: AModel_ids"
DB Query: create table if not exists AModel_AModel_Mid_Table (AModel_ids TEXT, AModel_ids TEXT)

what‘s the crash reason?

'NSInvalidArgumentException', reason: '+[JRDBMgr _clearObjCaches]: unrecognized selector sent to class 0x1005078a0'

请问如何设置联合主键

1>请问如何取消默认的主键_ID.根据你提供的替换主键的方法+ (NSString *)jr_customPrimarykey {
return @"userId";
}

  • (id)jr_customPrimarykeyValue {
    return self.userId;
    }
    其中userid是字符串类型.这样还是原有的_ID主键
    2>如果需要设置两个主键,请问怎么设置?

最新版本的自定义主键和键值有BUG

pragma mark - save one

/**

  • 保存单条,不关联保存
    */
  • (BOOL)jr_saveOneOnly:(id)one {
    AssertRegisteredClazz([one class]);
    if ([[one class] jr_customPrimarykey]) { // 自定义主键
    NSAssert([one jr_customPrimarykeyValue] != nil, @"custom Primary key should not be nil");
    // NSObject *old = (NSObject *)[self jr_getByPrimaryKey:[one jr_customPrimarykeyValue] clazz:[one class]];
    NSAssert(![self jr_count4PrimaryKey:[one jr_customPrimarykeyValue] clazz:[one class]], @"primary key is exists");
    } else { // 默认主键
    NSAssert(one.ID == nil, @"The obj:%@ to be saved should not hold a ID", one);
    }

JRSql *sql = [JRSqlGenerator sql4Insert:one toDB:self];
[one setID:[JRUtils uuid]];
[sql.args insertObject:one.ID atIndex:0];
BOOL ret = [self jr_executeUpdate:sql];

if (ret) {
// 保存完,执行block
[one jr_executeFinishBlocks];
}
return ret;
}

上面的代码有问题....无论如何都是保存了[JRUtils uuid]这个Value 还有[[one class] jr_customPrimarykey]调用了设置主键而不是设置主键的默认值......应该是[one jr_customPrimarykeyValue]吧...

最后改成这样就没问题了
/**

  • 保存单条,不关联保存
    */

  • (BOOL)jr_saveOneOnly:(id)one {
    AssertRegisteredClazz([one class]);
    if ([one jr_customPrimarykeyValue]) { // 自定义主键
    NSAssert([one jr_customPrimarykeyValue] != nil, @"custom Primary key should not be nil");
    // NSObject *old = (NSObject *)[self jr_getByPrimaryKey:[one jr_customPrimarykeyValue] clazz:[one class]];
    NSAssert(![self jr_count4PrimaryKey:[one jr_customPrimarykeyValue] clazz:[one class]], @"primary key is exists");
    JRSql *sql = [JRSqlGenerator sql4Insert:one toDB:self];
    [one setID:[one jr_customPrimarykeyValue]];
    [sql.args insertObject:one.ID atIndex:0];
    BOOL ret = [self jr_executeUpdate:sql];

    if (ret) {
    // 保存完,执行block
    [one jr_executeFinishBlocks];
    }
    return ret;
    } else { // 默认主键
    NSAssert(one.ID == nil, @"The obj:%@ to be saved should not hold a ID", one);
    JRSql *sql = [JRSqlGenerator sql4Insert:one toDB:self];
    [one setID:[JRUtils uuid]];
    [sql.args insertObject:one.ID atIndex:0];
    BOOL ret = [self jr_executeUpdate:sql];

    if (ret) {
    // 保存完,执行block
    [one jr_executeFinishBlocks];
    }
    return ret;
    }
    }

不知道理解有没有问题....还是我的写法有问题

多表联查

当需要多表联查时,如何做??!!

swift和objective-c混编项目引入此库后打断点后直接闪退。

Btl was compiled with optimization - stepping may behave oddly; variables may not be available.
Message from debugger: The LLDB RPC server has crashed. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log.

查看carsh log显示信息如下:System Integrity Protection: enabled

Crashed Thread: 8 RPC packet thread for client tid 006737a7 (6764455)

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY

Application Specific Information:
Stack dump:
0. While loading conformances for 'BTLRemotePushHelper' in module 'Btl'

  1. While reading inherited conformance for type 'BTLRemotePushHelper'
  2. While cross-referencing conformance for 'NSObject' in module 'ObjectiveC'
  3. While ... to 'JRPersistent' in module '__ObjC'
  4. If you're seeing a crash here, check that your SDK and dependencies are at least as new as the versions used to build 'Btl'

abort() called

大概推测应该是jrdb问题,但是不知道如何解决,希望作者能个方案帮我解决下问题。best wishes!

pod JRDB

在pod下update后发现JRDB来到1.4.6,但是在代码里面报错,无法编译通过
@implementation JRDBQueue

  • (instancetype)initWithPath:(NSString *)aPath flags:(int)openFlags vfs:(NSString *)vfsName {
    if (self = [super initWithPath:aPath flags:openFlags vfs:vfsName]) {
    dispatch_queue_set_specific(self->_queue, kJRDBQueueSpecificKey, (__bridge void *)self, NULL);
    }
    return self;
    }

显示 JRDBQueue.m:15:43: 'JRDBQueue' does not have a member named '_queue'

这种情况应该怎么办???

查询的问题

你好,查询是怎么用的,有没有具体的demo?

一个模型生成多张表的问题

我看了源码,写的很不错,我这里遇到一个问题就是一个模型只能生成一张表,而不能生成多张表,或者自定义表名,不知道你有没有好的解决方案

Property name被重构?

model某个property name被refactor了怎么办?好像FMResultSet查出来的结果集无法映射到model上了。

数据库不支持int64的数据类型吗?

我的主键是int64的数据类型,我插入时成功了,但查出来的数据_musicId的值全部是 0 这个是怎么回事呀?

`#ifndef _INT64_T
#define _INT64_T
typedef long long int64_t;
#endif /* _INT64_T */

@Property(nonatomic,assign) int64_t Id; //歌曲id

#pragma - mark JRDB

  • (NSString *)jr_customPrimarykey
    {
    return @"_Id";
    }

//主键的值

  • (id)jr_customPrimarykeyValue
    {
    return @(self.Id);
    }`

能否支持自增整形ID?

你好,项目里面需要使用整形自增ID,试过了貌似必须有一个_ID的字符串字段作为ID,能否支持自增整形ID?

最好提供多表支持

对于项目中的多用户支持,每个用户对应一个同种类但是名字不同的表, ToDoListTable_liLei, ToDoListTable_wangMeiMei

建议

由于Sqlite支持自增长主键,我觉得主键ID可以设置为自增长主键,这样设置,排序查询会快很多。创建表语句可改为:create table if not exists xxx (_ID INTEGER primary key autoincrement)

一个模型如何创建多个表

需要是一个聊天 的session表 ,每条数据都对应 一个message 表 。这样就需要创建多个 message表 。可不可以实现 。

大批量导入数据会很慢

2018-08-13 19:16:20.643687+0800 TrafficLight[6763:5763664] <instant>[CSVParserUtils.swift:line:184:函数:parserCSVIntoDbOfTypeLane(csvReader:callback:)]- CSV 开始入库,数据量==14354 2018-08-13 19:17:34.635045+0800 TrafficLight[6763:5763664] <instant>[CSVParserUtils.swift:line:187:函数:parserCSVIntoDbOfTypeLane(csvReader:callback:)]- CSV 结束入库,数据量==14354 2018-08-13 19:17:36.686191+0800 TrafficLight[6763:5763664] <instant>[CSVParserUtils.swift:line:127:函数:parserCSVIntoDbOfTypeNet(csvReader:callback:)]- CSV 开始入库,数据量==7094 2018-08-13 19:18:19.664702+0800 TrafficLight[6763:5763664] <instant>[CSVParserUtils.swift:line:130:函数:parserCSVIntoDbOfTypeNet(csvReader:callback:)]- CSV 结束入库,数据量==7094

readme写得看不太明白

如果我用最新版本,旧版本下面的都不用看了吗?readme中英文混合,看着有点别扭

使用j_select

J_Select([NoteSqlModel class]);

报错,不支持c99

如果对象的属性数组中是基础数据类型的问题

你好,在使用你的框架时,发现如果对象的属性数组中是基础数据类型,如:NSString. 我该如何处理保存?

@interface Student : NSObject

@property (assign, nonatomic) NSInteger num;

@property (copy, nonatomic) NSString *name;

@property (assign, nonatomic) NSInteger sex;

@property (assign, nonatomic) NSInteger age;

@property (copy, nonatomic) NSString *address;

@property (strong, nonatomic) NSArray <NSString *> *books;

@end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.