我有一个工作的应用程序,我正在努力将其转换为Xcode 4.2中的ARC.其中一个预检警告涉及self强烈捕获导致保留周期的块.我已经制作了一个简单的代码示例来说明问题.我相信我理解这意味着什么,但我不确定实现这种情况的"正确"或推荐方法.
代码示例:
// code sample
self.delegate = aDelegate;
self.dataProcessor = [[MyDataProcessor alloc] init];
self.dataProcessor.progress = ^(CGFloat percentComplete) {
[self.delegate myAPI:self isProcessingWithProgress:percentComplete];
};
self.dataProcessor.completion = ^{
[self.delegate myAPIDidFinish:self];
self.dataProcessor = nil;
};
// start the processor - processing happens asynchronously and the processor is released in the completion block
[self.dataProcessor startProcessing];
Run Code Online (Sandbox Code Playgroud)
问题:我在做什么"错误"和/或如何修改它以符合ARC惯例?
我已经读完了这个帖子:"__block"关键字是什么意思?讨论了什么__block用于但我对其中一个答案感到困惑.它说__block是用来避免保留周期,但它下面的评论让我不确定.
我正在使用这样的东西:
self.someProperty = x; //where x is some object (id)
__block __weak VP_User *this = self;
//begin a callback-style block
this.someProperty = nil;
Run Code Online (Sandbox Code Playgroud)
我需要同时使用__block和__weak?看起来这种方式有什么明显的问题吗?
使用块时,为什么某些变量需要__block,而其他变量(如函数参数)则不需要?
在我的applicationDidFinishLaunching:方法中,我创建了一个对象并在其上调用异步方法,如下所示:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
Foo *foo = [[Foo alloc] init];
[foo asynchronousMethodWithCompletion:^{
// Location A
}];
// Location B
}
Run Code Online (Sandbox Code Playgroud)
如果我不使用ARC,我必须在哪里放[foo release]?在完成块(位置A)内或异步方法调用之后(位置B)?或者根本不重要?
我知道__block块的标量变量需要存储类型才能看到它们的更新,但是何时需要对象?我相信__weak应该在捕获要在块中使用的自引用时使用,但我不知道何时需要实际使用__block普通对象的存储类型.
谁能解释这个块语法是如何工作的?
AStreamBuilder stream_builder = [ [ ^( void )
{
// some more code..
return (NSInputStream *)[ NSInputStream inputStreamWithFileAtPath: some_path ];
} copy ] autorelease ];
return stream_builder;
Run Code Online (Sandbox Code Playgroud)
这个街区的名称是什么?为什么要复制块然后自动释放?我对这里发生的事情感到困惑..据说该块返回AStreamBuilder,但是在块体内它返回一个NSInputStream实例.
任何人都可以打破这个吗?
现在我有一部分代码如下:
__strong MyRequest *this = self;
MyHTTPRequestOperation *operation = [[MyHTTPRequestOperation alloc]initWithRequest:urlRequest];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *request, id responseObject) {
[this requestFinished:request];
}
failure:^(AFHTTPRequestOperation *request, NSError *error) {
[this requestFailed:request withError:error];
}];
Run Code Online (Sandbox Code Playgroud)
我主要是这样做的,因为其他一些类继承自此代码所在的类,并实现自己的requestFinished和requestFailed.
如果我将自引用更改为__weak,我会开始收到一些EXC_BAD_ACCESS错误.使用__strong引用一切正常,但我担心创建一个保留周期.请注意,我正在使用ARC.
此代码是否会创建一个会导致问题的保留周期?任何简单的解决方案?我可以遵循任何不同的方法让继承类实现自己的方法来处理响应?
我想在块中使用弱自我,但是在块中这个 weakSelf 变为 nil
刚刚创建,在阻止之前(尝试使用不同的变体) - 看起来一切正常

但后来在块中 - 每个变体都为零

做错了什么?谁能解释一下?
编辑
SPHVideoPlayer *videoPlayer = [[SPHVideoPlayer alloc] initVideoPlayerWithURL:urlToFile];
[videoPlayer prepareToPlay];
Run Code Online (Sandbox Code Playgroud)
初始化
#pragma mark - LifeCycle
- (instancetype)initVideoPlayerWithURL:(NSURL *)urlAsset
{
if (self = [super init]) {
[self initialSetupWithURL:urlAsset];
}
return self;
}
- (void)initialSetupWithURL:(NSURL *)url
{
NSDictionary *assetOptions = @{ AVURLAssetPreferPreciseDurationAndTimingKey : @YES };
self.urlAsset = [AVURLAsset URLAssetWithURL:url options:assetOptions];
}
Run Code Online (Sandbox Code Playgroud)
还有使用块的方法
- (void)prepareToPlay
{
__weak typeof(self) weakSelf = self;
__weak SPHVideoPlayer *weakSealf2 = self;
NSArray *keys = @[@"tracks"];
[self.urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{ …Run Code Online (Sandbox Code Playgroud)