Сохраните циклы с одноэлементным в Objective-C - PullRequest
0 голосов
/ 11 октября 2018

У меня есть одноэлементный класс с именем MyManager.Я использую self внутри своих блоков: requestSomeInfo и requestSomeInfoWithString.И метод requestSomeInfoWithString получает self.string в качестве параметра.Приводит ли этот код к сохранению циклов в обоих блоках?

Проект с ARC.

@interface MyManager : NSObject

+ (instancetype)sharedInstance;
- (void)requestSomeInfo:(void (^)(BOOL success))completion;
- (void)requestSomeInfoWithString:(NSString *)string completion:(void (^)(BOOL success))completion;

@end

@implementation MyManager

+ (instancetype)sharedInstance {
    static MyManager *shared = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shared = [MyManager new];
    });
    return shared;
}

@end


@interface MyClass

@property string;

@end

@implementation MyClass
.....

[[MyManager sharedInstance] requestSomeInfo:^(BOOL success) {
if (success) {
    [self someAction];
}
}];

[[MyManager sharedInstance] requestSomeInfoWithString:self.string completion:^(BOOL success) {
    if (success) {
        [self someAction];
    }
}];

.....
@end

1 Ответ

0 голосов
/ 12 октября 2018

В вашем описании не упоминается MyClass, а в вашем фрагменте кода -.По фрагменту кода у вас есть методы в MyClass, которые делают вызовы методов в MyManager.Эти вызовы напрямую передают блоки как аргументы, не сохраняя ссылки на переменные экземпляра на эти блоки;вы не показываете, хранит ли MyManager ссылки на блоки, которые он получает, в своих переменных экземпляра, но разумно предположить, что это так.

Переданные блоки используют self, который ссылается на экземплярMyClass, который создал блок.

Итак, с точки в методах MyManager, где они сохраняют ссылки на восстановленный блок в переменные экземпляра, вы получаете следующую цепочку ссылок:

shared -> ваш MyManager экземпляр

экземпляр MyManager -> переданный в блоке

переданный блок -> ссылается на экземпляр MyClass, который его создал

Это не ссылочный цикл, поэтому, если у вас нет большего количества межобъектных ссылок в вашем реальном коде, у вас нет цикла.

A ссылочный цикл - этоне так уж плохо, они могут быть созданы в ходе обычного выполнения программы и иногда могут быть жизненно важны для поддержания соответствующих объектов;цикл может быть временным / с конечным временем жизни, после которого по крайней мере одно из звеньев в цикле разрывается.Референтный цикл становится плохим сохраняющим циклом только тогда, когда они непреднамеренно приводят к тому, что экземпляры объектов живут за пределами своего требуемого времени жизни ...

Что в конечном итоге приводит нас к вашему коду.У вас есть общий экземпляр из MyManager, который, вероятно, живет с момента создания до завершения вашей программы.В этом случае вы храните ссылки на блоки, а эти блоки хранят ссылки на MyClass экземпляры ... Это где-то, где у вас может быть непреднамеренная "утечка";если ваши MyManager методы не стирают (сохраняют nil в) переменные экземпляра, которые ссылаются на эти блоки, когда эти ссылки больше не требуются (вероятно, сразу после вызова ссылочного блока), то вы можете иметь долгосрочные непреднамеренные ссылки на MyClass экземпляров, которые долгое время были отброшены.Удалите эти ссылки на блоки, как только они будут использованы, и возможность исчезнет.

Надеюсь, что все имеет смысл!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...