从NSOperation对象访问另一个类的属性

时间:2011-01-30 19:17:42

标签: multithreading cocoa concurrency

亲爱的社区。 我有NSOperation子类的属性:

@property(readwrite, getter=isCancelled) BOOL cancelled;

从那里我创建子类NSObject的对象(来自init):

database = [[[MySQLIXC alloc] initWithQuene:iQuene andCarrier:startForCarrier withState:cancelled] retain];

在这个自定义对象中,我尝试声明本地iVar:

@interface MySQLIXC :  NSObject {
       BOOL _currentQueueStatus;

在init中:

- (id)initWithQuene:(NSUInteger)quene andCarrier:(NSString *)carrierName withState:(BOOL)currentQueueStatus;
    _currentQueueStatus = currentQueueStatus;

但是currentQueueStatus总是为null。 有人可以建议问题所在地吗?

1 个答案:

答案 0 :(得分:1)

1)你应该避免为你的添加重新声明已实现的子类接口(例如-[NSOperation isCancelled]存在)

2)从两个保留计数开始是非常不寻常的:

database = [[MySQLIXC alloc] initWithQuene:iQuene andCarrier:startForCarrier withState:cancelled];
[otherThingThatHoldsAReference setDatabase:database];

而不是:

database = [[[MySQLIXC alloc] initWithQuene:iQuene andCarrier:startForCarrier withState:cancelled] retain];

3)_currentQueueStatus不是null它是BOOL,而是signed char。它应该是0NO)或1YES)。

4)什么是currentQueueStatus?更多代码可以帮助您获得更具体的答案。

编辑:更新以澄清以回应评论

/* things would look different if you subclass MONOperation */
@interface MONOperation : NSOperation
{
@private
    MySQLIXC * sqlIxc;
    BOOL didCancelDatabaseRequest;
}

/*
do not use isCancelled for your name - NSOperation declares this method, and
its implementation is well defined. this would override the implementation
and likely cause runtime errors.

specifically, NSOperation/NSOperationQueue uses cancel and isCancelled in its
interface and state. if you must cancel, then call cancel from cancelDatabaseRequest.
you may override cancel, but call [super cancel] in your implementation.
*/
@property (readonly) BOOL didCancelDatabaseRequest;
@property (retain) MySQLIXC * sqlIxc;

@end

@implementation MONOperation

/* ... */

- (BOOL)didCancelDatabaseRequest
{
    return didCancelDatabaseRequest;
}

- (void)cancelDatabaseRequest /* in this example, there is no sense making cancelDatabaseRequest publicly visible */
{
/* for example */
    assert(self.sqlIxc);
    self.sqlIxc = nil;
    didCancelDatabaseRequest = YES;
    [self cancel]; /* do this rather than overriding NSOperation's cancellation interfaces in your subclass */
}

- (void)main
{
    NSAutoreleasePool * pool = [NSAutoreleasePool new];
    assert(self.sqlIxc);
    self.sqlIxc.doStuff;
    if (self.sqlIxc.didTimeout || self.sqlIxc.couldNotAccessFile) {
        [self cancelDatabaseRequest];
    }
    else {
    /* use the result */
    }
    [pool release];
}

@end