0

我正在从 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对象指向Bookthrough属性,book但这不会创建ARC 保留循环,因为book属性是weak

但是,如果 API 给了我Author第一个,并且我下载了它Book,那么一旦我设置它的方法返回,该对象就会被释放,因为相同的属性是weak.

我想到了几种解决方法:

  • 创建一个Content同时存储两者的对象(对于多对多关系不可行)
  • 创建单独的strongBookweakBook属性,然后创建一个readonly名为bookwhich 检查设置并返回该属性的属性

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

有没有办法使用 Objective-C 运行时动态地将属性从weakto更改为strong(反之亦然)?

更新:我收到了一些关于如何解决这个问题的建议,我自己想不出这些建议。这个问题特别是关于是否有一种方法可以(a)为类的特定实例动态重新定义@properties,或者(b)在特定情况下覆盖AR​​C的retain/release行为(因为这个问题在MRC中不存在)。

4

2 回答 2

1

只是在黑暗中拍摄,但您可以创建属性而不指定,然后将动态与运行时 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
于 2013-12-05T16:21:36.910 回答
0

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

于 2013-06-06T20:10:19.277 回答