有条件地使@属性强或弱



我正在从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对象来存储两者(对于多对多关系不可行)
  • 创建单独的strongBookweakBook属性,然后创建一个名为bookreadonly属性,该属性检查设置并返回

这两种方法对我来说都很混乱,尽管第二种方法更可取。

是否有一种方法可以动态地改变属性从weakstrong(反之亦然)使用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

在下载期间,创建一个可变字典来临时存储在书之前到达的作者对象。当收到一本书时,查看该数组并查看作者信息是否在那里,如果有,则附上它。当您完成后清除可变数组

最新更新