我已经阅读了Apple的Blocks Programming Topics和我的尽职调查在线搜索,但我仍然不清楚我是否正确实现我的块。我有一组客户端作为在发送NSNotification时填充的属性。客户端用作tableview数据源。下面的代码有效,但我很好奇是否将自我置于保留周期。我应该执行__block id theClients = self.clients;
之类的操作,然后在块内引用theClients
吗?
@property (strong, nonatomic) NSMutableArray *clients;
NSNotificationCenter *notifyCenter = [NSNotificationCenter defaultCenter];
__block id observer = [notifyCenter addObserverForName:queryHash
object:nil
queue:[[NSOperationQueue alloc] init]
usingBlock:^(NSNotification* notification){
// Explore notification
if ([[notification.userInfo objectForKey:kdatasetReturnKey] objectAtIndex:0]) {
NSArray *rows = [[notification.userInfo objectForKey:kdatasetReturnKey] objectAtIndex:0];
if (self.clients)
{
self.clients = nil;
}
self.clients = [[NSMutableArray alloc] initWithCapacity:rows.count];
for (NSDictionary *row in rows) {
[self.clients addObject:row];
}
} else {
NSLog(@"CLIENTS ERROR Returned: %@",[notification.userInfo objectForKey:kerrorReturnKey]);
}
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
答案 0 :(得分:8)
访问clients属性没有问题,因为它是一个强大的(即保留的)属性。所以这里不需要__block
。
一个问题可能是发送通知时self
可能不再存在。然后你将访问解除分配的对象,应用程序可能会崩溃!为避免这种情况,您应该使用dealloc
方法删除观察者。
__block
之前的id observer
绝对是必需的!
修改强>
在iOS 5中,您可以使用弱引用安全地捕获self
:
__weak id weakSelf = self;
然后在块内,您可以安全地使用weakSelf.clients
。当对象被释放时,变量weakSelf将自动变为nil。
答案 1 :(得分:3)
是的,您有一个保留周期,至少在通知发生之前。当您访问块中的clients
ivar时,块将保留自己。它将被通知中心中的块保留,直到通知发生(因为您在块的末尾移除了观察者)。如果在你的情况下这是不可取的,你可以使用弱引用自我。
NSNotificationCenter *notifyCenter = [NSNotificationCenter defaultCenter];
__weak id weakSelf = self;
id observer = [notifyCenter addObserverForName:queryHash
object:nil
queue:[[NSOperationQueue alloc] init]
usingBlock:^(NSNotification* notification) {
if (weakSelf) {
if ([[notification.userInfo objectForKey:kdatasetReturnKey] objectAtIndex:0]) {
NSArray *rows = [[notification.userInfo objectForKey:kdatasetReturnKey] objectAtIndex:0];
if (weakSelf.clients)
{
weakSelf.clients = nil;
}
weakSelf.clients = [[NSMutableArray alloc] initWithCapacity:rows.count];
for (NSDictionary *row in rows) {
[weakSelf.clients addObject:row];
}
} else {
NSLog(@"CLIENTS ERROR Returned: %@",[notification.userInfo objectForKey:kerrorReturnKey]);
}
}
[[NSNotificationCenter defaultCenter] removeObserver:observer];
}];
我认为您无需__block
限定observer
。
目前还不清楚你是否在这里使用基于块的API。如果您不想担心潜在的保留周期,可以使用addObserver:selector:name:object:
并将通知回调的主体放在实例方法中。