Mat*_*rix 10 iphone weak-references objective-c
我有这样的情况:
NSMutableArray * A = [[NSMutableArray alloc]initwithObjects:@"one",nil];
NSMutableArray * B = [[NSMutableArray alloc]initwithObjects:@"two",nil];
[A addObject:B];
[B addObject:A];
Run Code Online (Sandbox Code Playgroud)
现在这里是一个保留周期,我怎样才能打破这个保留周期?(使用弱引用)....在上面的例子中.谢谢
Nic*_*rge 12
我首先会质疑你需要这样做的原因 - 但如果你确定它是最好的数据架构,我会用NSValue.要在Foundation集合类中存储对象的引用(不保留它),您可以使用+[NSValue valueWithNonretainedObject:]:
NSMutableArray *a = [[NSMutableArray alloc] initwithObjects:@"one", nil];
NSMutableArray *b = [[NSMutableArray alloc] initwithObjects:@"two", nil];
[a addObject:b];
[b addObject:[NSValue valueWithNonretainedObject:a]];
Run Code Online (Sandbox Code Playgroud)
然后,为了稍后从NSValue实例获取您的对象,您将执行以下操作:
NSMutableArray *c = (NSMutableArray *) [[b objectAtIndex:index] nonretainedObjectValue];
Run Code Online (Sandbox Code Playgroud)
我从使用变更的回答+[NSValue valueWithPointer:]到+[NSValue valueWithNonretainedObject:],因为ARC下,编译器会抱怨(由于从对象类型铸造const void *).虽然功能相同,但是类型转换和方法名称更有意义(并且编译器实际上允许您编译而不诉诸hackery).
我过去解决这个问题的方法是使用NSProxy的子类来打破循环.我将有一个对象存储对其中一个数组的弱引用,并将除内存管理之外的所有消息传递给它.
????? NSArray A <?????
? ?
? ?
v weak ?
ACWeakProxy ? ? ? ? ? > NSArray B
Run Code Online (Sandbox Code Playgroud)
@interface ACWeakProxy : NSProxy {
id _object;
}
@property(assign) id object;
- (id)initWithObject:(id)object;
@end
Run Code Online (Sandbox Code Playgroud)
@implementation ACWeakProxy
@synthesize object = _object;
- (id)initWithObject:(id)object {
// no init method in superclass
_object = object;
return self;
}
- (BOOL)isKindOfClass:(Class)aClass {
return [super isKindOfClass:aClass] || [_object isKindOfClass:aClass];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation setTarget:_object];
[invocation invoke];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [_object methodSignatureForSelector:sel];
}
@end
Run Code Online (Sandbox Code Playgroud)
然后你的代码变成了
NSMutableArray * A = [[NSMutableArray alloc] initwithObjects:@"one", nil];
NSMutableArray * B = [[NSMutableArray alloc] initwithObjects:@"two", nil];
[A addObject:B];
ACWeakProxy * proxy = [[ACWeakProxy alloc] initWithObject:A];
[B addObject:proxy];
[proxy release];
// will print "two"
NSLog(@"%@", [[[B objectAtIndex:1] objectAtIndex:1] objectAtIndex:0]);
Run Code Online (Sandbox Code Playgroud)
但是,在您仍在使用它时,请确保您的弱参考不会消失.
你可以:
使用CFArrayCreateMutable()并设置retain和release回调NULL:
CFArrayCallBacks acb = { 0, NULL, NULL, CFCopyDescription, CFEqual };
NSMutableArray *noRetain = (NSMutableArray *)CFArrayCreateMutable(NULL, 0, &acb);
Run Code Online (Sandbox Code Playgroud)更好的是,退一步思考如何以不同的方式实现自己想要的东西.通过适当的设计,甚至可能不会出现此问题.
在iPhone中,没有弱引用的概念。在你的情况下,我相信这会导致它们中的任何一个过度释放的问题。
通常,对于两堂课,我会这样做:
让一个类通过保留来拥有另一个类,而另一个类则使用分配。一些示例代码可能会澄清它
A级
@interface A {
}
@property (nonatomic, retain) B *b;
@end
Run Code Online (Sandbox Code Playgroud)
B级
@interface B {
}
@property (nonatomic, assign) A *a;
@end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10020 次 |
| 最近记录: |