у меня есть такая ситуация:
NSMutableArray * A = [[NSMutableArray alloc]initwithObjects:@"one",nil];
NSMutableArray * B = [[NSMutableArray alloc]initwithObjects:@"two",nil];
[A addObject:B];
[B addObject:A];
теперь вот цикл сохранения, как я могу разорвать этот цикл сохранения? (используя слабую ссылку) .... в приведенном выше примере. Спасибо
Я бы поставил под сомнение причину, по которой вам нужно это сделать в первую очередь, но если вы решите, что это лучшая архитектура данных, я бы использовал 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]];
. Затем, чтобы позже получить объект из NSValue
, вы должны сделать это:
NSMutableArray *c = (NSMutableArray *) [[b objectAtIndex:index] nonretainedObjectValue];
Я изменил ответ с использования +[NSValue valueWithPointer:]
на +[NSValue valueWithNonretainedObject:]
. , так как под ARC компилятор будет жаловаться (из-за приведения типа объекта к const void *
). Хотя функционально то же самое, приведение типов и имя метода имеют больше смысла (и компилятор фактически позволит вам скомпилировать, не прибегая к хакерству).
Как я решил эта проблема в прошлом заключалась в использовании подкласса NSProxy для разрыва цикла. У меня будет объект, который хранит слабую ссылку на один из массивов и передает ему все сообщения, кроме сообщений управления памятью.
┌──── NSArray A <────┐
│ │
│ │
v weak │
ACWeakProxy ┈ ┈ ┈ ┈ ┈ > NSArray B
@interface ACWeakProxy : NSProxy {
id _object;
}
@property(assign) id object;
- (id)initWithObject:(id)object;
@end
@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
Тогда ваш код становится
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]);
Однако вы сами должны убедиться, что ваша слабая ссылка не исчезнет, пока вы ее используете.