标签: retain-cycle

如何正确处理带参数的Swift块中的弱自我

在我TextViewTableViewCell,我有一个变量来跟踪块和一个配置方法,其中传入和分配块.
这是我的TextViewTableViewCell班级:

//
//  TextViewTableViewCell.swift
//

import UIKit

class TextViewTableViewCell: UITableViewCell, UITextViewDelegate {

    @IBOutlet var textView : UITextView

    var onTextViewEditClosure : ((text : String) -> Void)?

    func configure(#text: String?, onTextEdit : ((text : String) -> Void)) {
        onTextViewEditClosure = onTextEdit
        textView.delegate = self
        textView.text = text
    }

    // #pragma mark - Text View Delegate

    func textViewDidEndEditing(textView: UITextView!) {
        if onTextViewEditClosure {
            onTextViewEditClosure!(text: textView.text)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我在我的cellForRowAtIndexPath方法中使用configure方法时,如何在我传入的块中正确使用弱自我.
这是我没有弱自我的情况:

let myCell = tableView.dequeueReusableCellWithIdentifier(textViewCellIdenfitier) as TextViewTableViewCell …
Run Code Online (Sandbox Code Playgroud)

ios retain-cycle swift

143
推荐指数
7
解决办法
11万
查看次数

对NSTimer目标的弱参考以防止保留周期

我用的NSTimer是这样的:

timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:self selector:@selector(tick) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)

当然,NSTimer保留了创建保留周期的目标.此外,self不是一个UIViewController所以我没有任何东西viewDidUnload,我可以无效的计时器来打破循环.所以我想知道我是否可以使用弱引用:

__weak id weakSelf = self;
timer = [NSTimer scheduledTimerWithTimeInterval:30.0f target:weakSelf selector:@selector(tick) userInfo:nil repeats:YES];
Run Code Online (Sandbox Code Playgroud)

我听说计时器必须无效(我想从运行循环中释放它).但我们可以在我们的dealloc中做到这一点,对吗?

- (void) dealloc {
    [timer invalidate];
}
Run Code Online (Sandbox Code Playgroud)

这是一个可行的选择吗?我已经看到人们处理这个问题的方法很多,但我还没有看到这个.

objective-c nstimer automatic-ref-counting retain-cycle

52
推荐指数
5
解决办法
2万
查看次数

深入了解保留周期

假设我们有三个对象:祖父母,父母和孩子.祖父母保留父母,父母保留孩子,孩子保留父母.祖父母释放父母.

在这种情况下会发生什么?

memory-management objective-c ios automatic-ref-counting retain-cycle

52
推荐指数
4
解决办法
4万
查看次数

在dispatch_async函数中使用弱自我

我读了很多关于__weak self在里面使用的帖子dispatch_async,现在我有点困惑.

如果我有 :

self.myQueue = dispatch_queue_create("com.biview.core_data", NULL);

dispatch_async(self.myQueue, ^(void){
    if (!self.var1) {
        self.var1 = ...;
    }
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        if ([self.var2 superview]) {
            [self.var2 removeFromSuperview];
        }

        [self.Label setText:text];
    });
});
Run Code Online (Sandbox Code Playgroud)

我需要使用吗__weak self?因为我读过在某些情况下dispatch_async 不需要__weak self.

请参阅此处的最新评论

weak-references ios objective-c-blocks retain-cycle

52
推荐指数
2
解决办法
3万
查看次数

引用嵌套块内的弱自我

假设我已经创建了一个弱自我使用

__weak typeof(self) weakSelf = self;
[self doABlockOperation:^{
        ...
}];
Run Code Online (Sandbox Code Playgroud)

在该块内,如果我嵌套另一个块:

[weakSelf doAnotherBlockOperation:^{
    [weakSelf doSomething];
}
Run Code Online (Sandbox Code Playgroud)

它会创建一个保留周期吗?我是否需要为weakSelf创建另一个弱引用?

__weak typeof(self) weakerSelf = weakSelf;
[weakSelf doAnotherBlockOperation:^{
    [weakerSelf doSomething];
}
Run Code Online (Sandbox Code Playgroud)

memory-management block ios automatic-ref-counting retain-cycle

40
推荐指数
2
解决办法
4万
查看次数

在从UIViewController调用的非保留完成中引用self时,weakSelf/strongSelf舞蹈真的是必要的吗?

假设我在UIViewController子类中有以下方法:

- (void)makeAsyncNetworkCall
{
    [self.networkService performAsyncNetworkCallWithCompletion:^{
        dispatch_async(dispatch_get_main_queue(), ^{
                [self.activityIndicatorView stopAnimating];
            }
        });
    }];
}
Run Code Online (Sandbox Code Playgroud)

我知道self块内部的引用导致UIViewController实例被块保留.只要performAsyncNetworkCallWithCompletion不将块存储在我的属性(或ivar)中NetworkService,我是否认为没有保留周期?

我意识到上面的这个结构将导致UIViewController被保留直到performAsyncNetworkCallWithCompletion完成,即使它是由系统早先发布的.但它可能(甚至可能吗?),系统会收回我的UIViewController 所有(更改到iOS 6的一个管理方式后UIViewController的后盾CALayer内存)?

如果有理由我必须做"弱自我/强自我舞蹈",它看起来像这样:

- (void)makeAsyncNetworkCall
{
    __weak typeof(self) weakSelf = self;
    [self.networkService performAsyncNetworkCallWithCompletion:^{
        typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) {
            return;
        }
        dispatch_async(dispatch_get_main_queue(), ^{
                [strongSelf.activityIndicatorView stopAnimating];
            }
        });
    }];
}
Run Code Online (Sandbox Code Playgroud)

但是我觉得这很难看,并且如果没有必要就想避免它.

objective-c uiviewcontroller ios objective-c-blocks retain-cycle

39
推荐指数
2
解决办法
9988
查看次数

我们是否需要在ARC的UIAnimationBlocks中使用__weak self?

我们是否需要在UIAnimation块中使用__weak self,如下所示?如果我们不指定自我弱,是否会产生保留周期问题?

[UIView animateWithDuration:animationDuration 
                      delay:0 
                    options:UIViewAnimationCurveEaseInOut 
                 animations:^{
        [self doSomething];
    } completion:^(BOOL finished) {
        if (finished) {
            [self doSomething];
        }
    }];
Run Code Online (Sandbox Code Playgroud)

我也对以下场景感到困惑.有什么想法吗?请分享您的意见.

[self.navController dismissViewControllerAnimated:animated 
                                       completion:^{
                                                      [self doSomething];
                                                  }];
Run Code Online (Sandbox Code Playgroud)

我们应该在这里使用弱者吗?

ios objective-c-blocks automatic-ref-counting retain-cycle

21
推荐指数
2
解决办法
1万
查看次数

递归阻塞并保留ARC中的循环

EDIT2:

不.建议的答案是关于异步调用.我想要并需要同步调用,就像在普通的标准递归调用中一样.

编辑:

__unsafe_unretained void (^unsafe_apply)(UIView *, NSInteger) ;
Run Code Online (Sandbox Code Playgroud)

在没有警告或错误的情况下编译,它在运行时失败,并将NULL存储到unsafe_apply中.

不过这个:

- (void) applyToView: (UIView *) view {

    UIColor * (^colorForIndex)(NSInteger) = ^(NSInteger index) {
        return [UIColor colorWithHue: ((CGFloat) index / 255.0f)
                          saturation: 0.5f
                          brightness: 0.5f
                               alpha: 1.0f] ;
    } ;

    void (^applyColors) (UIView *, NSInteger index) = ^(UIView * view, NSInteger index) {
        view.backgroundColor = colorForIndex(index) ;
    } ;

    void (^__block recurse_apply)(UIView *, NSInteger) ;

    void (^apply)(UIView *, NSInteger) = ^(UIView * view, NSInteger level) { …
Run Code Online (Sandbox Code Playgroud)

recursion objective-c objective-c-blocks automatic-ref-counting retain-cycle

20
推荐指数
1
解决办法
7270
查看次数

在此区块中强烈捕获"自我"可能会导致保留周期

我需要阻止.但编译器会发出警告

"在这个区块强势捕捉'自我'可能会导致保留周期"

__weak typeof(self) weakSelf = self;
[generalInstaImage setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:data[@"images"][@"low_resolution"][@"url"]]] placeholderImage:[UIImage imageNamed:@"Default"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
    NSLog(@"success");
    [generalInstaImage setImage: image];
    [weakSelf saveImage:generalInstaImage.image withName:data[@"id"]];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        NSLog(@"fail");
}];
Run Code Online (Sandbox Code Playgroud)

我尝试编写类似的例子weakSelf.generalInstaImage,但编译器生成错误而不编译.

objective-c ios objective-c-blocks automatic-ref-counting retain-cycle

19
推荐指数
1
解决办法
2万
查看次数

核心数据 - 中断父上下​​文的保留周期

假设我们在Core Data模型中有两个实体:Departments和Employees.
该部门与员工有一对多的关系.

我有以下ManagedObjectContexts:
- Root:连接到持久性存储协调器
- Main:具有父Root的上下文

当我想创建一个Employee我做到以下几点:
-我有一个部门的主要方面
-我在主环境中创建一个Employee
-我分配部门到员工的部门属性
-我省主要方面
-我保存根上下文

这将在Main上下文和Root上下文中创建一个保留周期.

如果我没有子上下文(所有在Root上下文中)这样做,那么我可以通过调用refreshObject:mergeChangesEmployee 来打破保留周期.在我使用这两个上下文的情况下,我仍然可以使用该方法来打破Main上下文的循环,但是我如何打破Root上下文的循环呢?

旁注:这是一个描述我的问题的简单示例.在仪器中,我可以清楚地看到分配数量的增长.在我的应用程序中,我的上下文比一个级别更深,导致更大的问题,因为我得到了一个新的实体分配,每个上下文保留周期我正在保存.

更新15/04:NSPrivateQueueConcurrencyType vs NSMainQueueConcurrencyType
保存两个上下文后,我可以refreshObject:mergeChanges使用Department对象在Main上下文中执行.正如预期的那样,这将使Department对象重新出错,打破保留周期并在该上下文中取消分配Department和Employee实体.

下一步是打破Root上下文中存在的保留周期(保存Main上下文已将实体传播到Root上下文).我可以在这里做同样的技巧,并refreshObject:mergeChanges在Department对象的Root上下文中使用.

奇怪的是:当NSMainQueueConcurrencyType创建我的根上下文(所有分配重新故障和dealloced)这工作得很好,但与NSPrivateQueueConcurrencyType创建我的根上下文(所有分配的重新出现故障,但不工作 dealloced ).

附注:Root上下文的所有操作都在performBlock(AndWait)调用中完成

更新15/04:第2部分
当我做另外一个(没用,因为没有改变)保存或回滚与NSPrivateQueueConcurrencyType根上下文,对象似乎被释放.我不明白为什么这与NSMainQueueConcurrencyType的行为不一样.

更新16/04:演示项目
我创建了一个演示项目:http://codegazer.com/code/CoreDataTest.zip

更新21/04:到达那里
感谢Jody Hagings的帮助!
我试图refreshObject:mergeChanges移出我的ManagedObject didSave方法.

你能解释一下我之间的区别吗:

[rootContext performBlock:^{
    [rootContext save:nil];
    for (NSManagedObject *mo in rootContext.registeredObjects)
        [rootContext refreshObject:mo mergeChanges:NO];
}];
Run Code Online (Sandbox Code Playgroud)

[rootContext performBlock:^{
    [rootContext save:nil];
    [rootContext performBlock:^{
        for (NSManagedObject *mo in rootContext.registeredObjects)
            [rootContext refreshObject:mo mergeChanges:NO];
    }];
}]; …
Run Code Online (Sandbox Code Playgroud)

core-data fault ios5 retain-cycle

14
推荐指数
1
解决办法
2345
查看次数