Objective-C访问块内的属性

Objective-C访问块内的属性,objective-c,ios,objective-c-blocks,Objective C,Ios,Objective C Blocks,我已经阅读了苹果的Blocks编程主题和我的尽职调查在线搜索,但我仍然不清楚我是否正确地实现了我的Blocks。我有一个客户端数组作为属性,在发送NSNotification时填充该属性。客户端用作tableview数据源。下面的代码是有效的,但我很好奇它是否将self置于一个保留周期中。我是否应该执行类似于\u块id theClients=self.clients的操作然后引用块内的客户端 @property(强,非原子)NSMutableArray*客户端 NSNotificationCen

我已经阅读了苹果的Blocks编程主题和我的尽职调查在线搜索,但我仍然不清楚我是否正确地实现了我的Blocks。我有一个客户端数组作为属性,在发送NSNotification时填充该属性。客户端用作tableview数据源。下面的代码是有效的,但我很好奇它是否将self置于一个保留周期中。我是否应该执行类似于
\u块id theClients=self.clients的操作然后引用块内的客户端

@property(强,非原子)NSMutableArray*客户端

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];
}];

访问clients属性没有问题,因为它是一个强(即保留)属性。所以这里不需要
\u块

一个问题是发送通知时,
self
可能不再存在。然后,您将访问解除分配的对象,应用程序可能会崩溃!为了避免这种情况,您应该在
dealloc
方法中删除观察者

id observer
之前的
\u块
绝对是必需的

编辑:

在iOS 5中,您可以使用弱引用安全地捕获
self

__weak id weakSelf = self;

然后在块内部,您可以安全地使用
weakSelf.clients
。解除分配对象时,变量weakSelf将自动变为nil。

是的,至少在通知发生之前,您有一个保留周期。当您访问块中的
客户端
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];
}];
我看不出有任何理由需要
\uu block
限定
观察者


还不清楚您是否从使用基于块的API中得到了什么。如果不想担心潜在的保留周期,可以使用
addObserver:selector:name:object:
将通知回调的主体放在实例方法中

“一个问题是,在发送通知时,self可能不再存在。然后,您将访问解除分配的对象,应用程序可能会崩溃!错误。
self
被块保留。@newacct也被self保留而不带弧?是的,
self
是块中使用的对象类型的局部变量,因此它会自动保留以便可以引用块中的self.properties导致内存泄漏?@Helium3,您应该使用
\u弱类型(self)weakSelf=self;