我们曾经犯过的低级错误

最后来提一个我们之前花了半个月才找出问题在哪的bug。问题出在protocol不该这么设计。我们写了一个class,这个class有两个method:beginstop,按下begin的时候要开始做一件事情,之后想要停止,就呼叫stop,要开始或要结束的时候,都会通知delegate。程式大概是这样:

@class MyClass;
@protocol MyClassDelegate <NSObject>
- (void)myClassWillBegin:(MyClass *)myClasss;
- (void)myClassDidBegin:(MyClass *)myClasss;
- (void)myClassWillStop:(MyClass *)myClasss;
- (void)myClassDidStop:(MyClass *)myClasss;
@end

@interface MyClass : NSObject
{
    id <MyClassDelegate> delegate;
}
- (void)begin;
- (void)stop;
@property (assign, nonatomic) id <MyClassDelegate> delegate;
@end

@implementation MyClass

- (void)begin
{
    [delegate myClassWillBegin:self];
    // Do something
    [delegate myClassDidBegin:self];
}
- (void)stop
{
    [delegate myClassWillStop:self];
    // Do something
    [delegate myClassDidStop:self];
}
@synthesize delegate;
@end

这个protocol有什么问题呢?前面提到,在UITableView的data source的method里头不该调用reloadData一样,这边的几个delegate method的实现里头,也都不该随意的调用beginstop,而我在myClassWillBegin:里头想要做一些检查,如果在某些条件下,这件事情不该跑起来,而应该停止,所以我在myClassWillBegin:里头调用了stop。但这么做,并不会让这件事情结束,因为begin这个method在对delegate呼叫完myClassWillBegin:之后,程式还是会继续往下走,所以还是把begin整个做完了。

这个protocol 应该这么设计:

@class MyClass;
@protocol MyClassDelegate <NSObject>
- (BOOL)myClassShouldBegin:(MyClass *)myClasss;
- (void)myClassDidBegin:(MyClass *)myClasss;
- (BOOL)myClassShouldStop:(MyClass *)myClasss;
- (void)myClassDidStop:(MyClass *)myClasss;
@end

@interface MyClass : NSObject
{
    id <MyClassDelegate> delegate;
}
- (void)begin;
- (void)stop;
@property (assign, nonatomic) id <MyClassDelegate> delegate;
@end
@implementation MyClass

- (void)begin
{
    if (![delegate myClassShouldBegin:self]) {
        return;
    }
    // Do something
    [delegate myClassDidBegin:self];
}
- (void)stop
{
    if (![delegate myClassShouldStop:self]) {
        return;
    }
    // Do something
    [delegate myClassDidStop:self];
}
@synthesize delegate;
@end

results matching ""

    No results matching ""