我正在从API下载对象列表以显示给用户。该列表混合了两种类型的对象。假设它们是书籍和作者的组合,类定义如下:
@interface Book : NSObject
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) Author *author;
@end
@interface Author : NSObject
@property (nonatomic, strong) NSString *fullName;
@property (nonatomic, weak) Book *book;
@end
每个Book
都可以从API下载其Author
的信息,反之亦然。
如果API给我一个Book
,我可以设置它的author
属性一旦我下载它。Author
对象通过book
属性指向Book
,但这不会创建ARC Retain Cycle,因为book
属性是weak
。
但是,如果API首先给我一个Author
,并且我下载了它的Book
,那么一旦我设置它的方法返回,该对象将被释放,因为相同的属性是weak
。
我想到了一些方法来解决这个问题:
- 创建一个
Content
对象来存储两者(对于多对多关系不可行) - 创建单独的
strongBook
和weakBook
属性,然后创建一个名为book
的readonly
属性,该属性检查设置并返回
这两种方法对我来说都很混乱,尽管第二种方法更可取。
是否有一种方法可以动态地改变属性从weak
到strong
(反之亦然)使用Objective-C运行时?
UPDATE:我得到了一些关于如何解决这个问题的建议,我自己没有麻烦。这个问题是关于是否有一种方法可以(a)动态地为类的特定实例重新定义@properties,或者(b)在特定情况下覆盖ARC的retain
/release
行为(因为这个问题在MRC中不存在)。
只是瞎猜,但你可以创建属性而不指定,然后在运行时api中使用动态。我没有测试它,但我认为它应该工作:
//.h file
#import <Foundation/Foundation.h>
@interface SomeObject : NSObject
@property(nonatomic) NSObject *object;
@end
//.m file
#import "SomeObject.h"
#import <objc/runtime.h>
@implementation SomeObject
@dynamic object;
-(void)setObject:(NSObject *)object
{
BOOL isWeak = NO;
if(isWeak)
{
objc_setAssociatedObject(self, "object", object, OBJC_ASSOCIATION_ASSIGN);
}
else
{
objc_setAssociatedObject(self, "object", object, OBJC_ASSOCIATION_RETAIN);
}
}
-(NSObject *)object
{
return objc_getAssociatedObject(self, "object");
}
@end
在下载期间,创建一个可变字典来临时存储在书之前到达的作者对象。当收到一本书时,查看该数组并查看作者信息是否在那里,如果有,则附上它。当您完成后清除可变数组