2

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

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

我已经尝试实现这个问题的代码:How to subclass UIScrollView and make the delegate property private但由于某种原因,它没有做任何事情(被覆盖的自定义方法永远不会被调用)。我也知道,如果您创建实现协议的自定义委托类(根据iPhone:我是否需要为 UIScrollViewDelegate(或任何委托)实现所有方法),您不必实现 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)”消息而崩溃。

所以我有点不知所措。

4

1 回答 1

2

我确实有一个如何子类化 UIScrollView 并使委托属性私有的实现。我猜你的代码为什么没有做任何事情:仔细检查你是否真的将滚动视图的 contentSize 设置为大于视图大小的东西。如果它更小,则没有滚动,只是弹跳,并且scrollViewDidScroll不会调用。

对于您的代码,您实际上在一行中有两个问题。首先,UIScrollView 的delegate 属性是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 设置为大于视图边界的值。否则将没有滚动,也没有委托调用。

于 2012-04-10T10:51:51.680 回答