iOS 5 Twitter框架& completionHandler block - 在这个块中强烈捕获'self'可能会导致保留周期“ [英] iOS 5 Twitter Framework & completionHandler block - "Capturing 'self' strongly in this block is likely to lead to a retain cycle"

查看:172
本文介绍了iOS 5 Twitter框架& completionHandler block - 在这个块中强烈捕获'self'可能会导致保留周期“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编程和Objective-C的新手,我正在尝试找出我的代码有什么问题。我已经阅读了一些关于块的内容,但我不知道到目前为止我所阅读的内容与我的代码有什么关系。

I am very new to programming and Objective-C and I am trying to work out what is wrong with my code. I have read a bit about blocks but I don't know how any of what I have read so far is relevant to my code.

我的代码使用的是iOS 5 Twitter Framework。我使用Apple提供的大部分示例代码,所以我实际上一开始并不知道我使用了一个块作为完成处理程序。

My code is using the iOS 5 Twitter Framework. I use most of the sample code that Apple provides so I actually had no clue at first that I was using a block for the completion handler.

现在我收到这两条消息来自Xcode 4说 1。块将被捕获的对象强烈保留的对象保留在此块中强烈捕获'self'可能会导致保留周期

Now I get those two messages from Xcode 4 saying "1. Block will be retained by an object strongly retained by the captured object" and "Capturing 'self' strongly in this block is likely to lead to a retain cycle".

基本上,我所做的是删除Apple在其完成处理程序中使用的代码(使用TWTweetComposeViewControllerResultCancelled和TWTweetComposeViewControllerResultDone的switch语句)并使用我的if语句 [imagePickerController sourceType]

Basically, what I did is to remove the code Apple used in their completion handler (switch statement with TWTweetComposeViewControllerResultCancelled & TWTweetComposeViewControllerResultDone) and used my if statements with [imagePickerController sourceType].

因此在图像后调用 sendTweet 已被添加到推文中。

So the sendTweet gets called after an image has been added to the tweet.

我希望有人可以向我解释为什么会这样,以及我如何解决它。另外:我可以将完成处理程序代码放入方法而不是块吗?

I hope someone can explain to me why this is happening and how I can solve it. Also: can I put the completion handler code into a method instead of a block?

- (void)sendTweet:(UIImage *)image
{
    //adds photo to tweet
    [tweetViewController addImage:image];

    // Create the completion handler block.
    //Xcode: "1. Block will be retained by an object strongly retained by the captured object"
    [tweetViewController setCompletionHandler:
                             ^(TWTweetComposeViewControllerResult result) {
            NSString *alertTitle,
                     *alertMessage,
                     *otherAlertButtonTitle,
                     *alertCancelButtonTitle;

            if (result == TWTweetComposeViewControllerResultCancelled) 
            {
                //Xcode: "Capturing 'self' strongly in this block is likely to lead to a retain cycle"
                if ([imagePickerController sourceType])
                {
                    alertTitle = NSLocalizedString(@"TCA_TITLE", nil);
                    alertMessage = NSLocalizedString(@"TCA_MESSAGE", nil);
                    alertCancelButtonTitle = NSLocalizedString(@"NO", nil);
                    otherAlertButtonTitle = NSLocalizedString(@"YES", nil);

                    //user taps YES
                    UIAlertView *alert = [[UIAlertView alloc] 
                                             initWithTitle:alertTitle 
                                                   message:alertMessage 
                                                  delegate:self   // Note: self
                                         cancelButtonTitle:alertCancelButtonTitle 
                                         otherButtonTitles:otherAlertButtonTitle,nil];
                    alert.tag = 1;
                    [alert show];                
                }            
            }


推荐答案

基本问题是你在一个块中使用 self 。该对象保留该块,块本身也保留该对象。所以你有一个保留周期,因此两者都可能永远不会被释放,因为它们都有一个指向它们的引用。 Fortunaly有一个简单的解决方法:

The basic problem is that you're using self within a block. The block is being retained by the object and the block itself retains the object, too. So you have a retain-cycle and thus both will probably never be released because both have a reference pointing towards them. Fortunaly there is a simple workaround:

通过使用所谓的自我弱引用,块将不再保留对象。然后可以释放该对象,该对象将释放该块(将 MyClass 设置为适当的类型):

By using a so-called weak reference to self the block will no longer retain the object. The object then can later be released which will release the block (set MyClass to the appropriate type):

// before your block
__weak MyObject *weakSelf = self;

在您的区块中,您现在可以使用 weakSelf 而不是 self 。请注意,这仅适用于使用ARC的iOS 5.

Inside your block you now can use weakSelf instead of self. Note that this is only for iOS 5 using ARC.

关于这一点,对如何在实现API时避免在块中捕获self?还介绍了如何在iOS 4和没有ARC的情况下避免这种情况。

Looking at this there is also a very good long explanation on How do I avoid capturing self in blocks when implementing an API? which also describes how to avoid this on iOS 4 and without ARC.

这篇关于iOS 5 Twitter框架& completionHandler block - 在这个块中强烈捕获'self'可能会导致保留周期“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆