覆盖scrollViewDidScroll时的问题,但不是UIScrollViewDelegate的所有其他方法

时间:2012-04-08 15:18:13

标签: ios5 uiscrollview uiscrollviewdelegate

好的,所以我针对这个问题进行了所有研究,但现有的解决方案似乎都没有解决我的问题,所以这里是:

  • 我有一个扩展UIScrollView(并包含UIView)的自定义类
  • 我想从UIScrollViewDelegate覆盖scrollViewDidScroll方法(但不是所有方法)

我已经尝试过实现此问题的代码:How to subclass UIScrollView and make the delegate property private但由于某种原因,它没有做任何事情(被覆盖的自定义方法永远不会被调用)。我还知道如果你创建一个实现协议的自定义委托类(按照iPhone: Do I need to implement all methods for UIScrollViewDelegate (or any delegate)),你不必实现UIScrollViewDelegate中的所有方法 - 但是当我这样做时:

MyScrollViewDelegate.h

@interface MyScrollViewDelegate: NSObject <UIScrollViewDelegate>

-(void)scrollViewDidScroll:(UIScrollView *)scrollView;

@end

MyScrollViewDelegate.m

@implementation MyScrollViewDelegate

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    NSLog(@"Custom scrollViewDidScroll called.");
    // -- some more custom code here --
    // ...
}

@end

在扩展UIScrollView

的子类中
// this scrollview is initiated by the NIB
- (void)awakeFromNib
{
    ...
    [self setDelegate:[[MyScrollViewDelegate alloc] init]];
}

但是当它编译并运行时,当我尝试滚动可滚动视图时,它会在调试控制台中使用EXC_BAD_ACCESS和一个神秘的“(lldb)”消息崩溃。

所以我有点不知所措。

1 个答案:

答案 0 :(得分:2)

我确实有How to subclass UIScrollView and make the delegate property private的实现可行。我猜你的代码没有做任何事情:仔细检查你是否真的将滚动视图的contentSize设置为比视图大小更大的代码。如果它更小则没有滚动,只是弹跳,并且scrollViewDidScroll没有被调用。

对于您的代码,您实际上在一行中有两个问题。首先,UIScrollView的委托属性是assign类型。也就是说,如果委托类没有保留在其他地方,它将在一段时间内消失,你将获得EXC_BAD_ACCESS。其次,通过将[[MyScrollViewDelegate alloc] init]分配给委托而不释放该对象,您可以创建一个孤立对象,该对象的引用计数为1且永远不会被释放。我的猜测是系统在运行时识别孤立对象并将其清理干净,然后在委托发送消息时得到EXC_BAD_ACCESS

如果您希望将您的版本与单独的委托一起使用,我会按如下方式修复它:

@interface MyScrollView: UIScrollView
{
    id<NSObject, MyScrollViewDelegate> dlgt;
    ...
}
...
@end

@implementation MyScrollView
- (void)awakeFromNib
{
    ...
    dlgt = [[MyScrollViewDelegate alloc] init];
    [self setDelegate:dlgt];
}

-dealloc
{
    [dlgt release];
    [super dealloc];
}
@end

但是,不要忘记将contentSize设置为大于视图边界的内容。否则就没有滚动和没有委托调用。