Objective c 子类化UIView与UIScrollView

Objective c 子类化UIView与UIScrollView,objective-c,subclass,Objective C,Subclass,好的,这可能是不可能的,但我有一个名为CompositeView的类,它是UIView的子类。它使用一些核心图形工作来根据一些选项生成自定义背景。这不是一个很大的班级,但随着我的需求的变化/增加/无论什么,我的班级肯定会增加。我遇到的问题是我在很多不同的地方经常使用这个类。但在一些地方,我需要它是UIScrollView的子类,而不是UIView。非常有趣的是,我可以简单地更改超类,而且一切都很好。但我不仅不希望所有其他视图都是UIScrollView,而且还干扰了其中一些视图的操作。所以我需要

好的,这可能是不可能的,但我有一个名为CompositeView的类,它是UIView的子类。它使用一些核心图形工作来根据一些选项生成自定义背景。这不是一个很大的班级,但随着我的需求的变化/增加/无论什么,我的班级肯定会增加。我遇到的问题是我在很多不同的地方经常使用这个类。但在一些地方,我需要它是UIScrollView的子类,而不是UIView。非常有趣的是,我可以简单地更改超类,而且一切都很好。但我不仅不希望所有其他视图都是UIScrollView,而且还干扰了其中一些视图的操作。所以我需要一个类,它有时是UIScrollView的子类,有时是UIView的子类

现在,我已经复制了CompositeView的所有接口/实现,将类名更改为CompositeSrollView,并将其继承更改为UIScrollView。它工作得很好,但现在我有两组代码,它们做完全相同的事情,只是从不同的父类继承。这使得他们两个都保持最新的痛苦


有更好的方法吗?

单继承语言强制您使用委托。您应该将添加的功能分解到一个单独的类中,然后为派生类实例化该类,然后将派生类中的数据写入实例。很痛

目标C有一个协议,该协议将描述添加的函数以及任何未重写的填隙片,如果您没有编写填隙片,编译器将出错。。。这仍然需要手动完成


Objective C还具有允许您扩展现有类的类别,但这些类别无法共享。您必须单独扩展每个类,这样才不会真正有帮助。

单继承语言强制您使用委派。您应该将添加的功能分解到一个单独的类中,然后为派生类实例化该类,然后将派生类中的数据写入实例。很痛

目标C有一个协议,该协议将描述添加的函数以及任何未重写的填隙片,如果您没有编写填隙片,编译器将出错。。。这仍然需要手动完成


Objective C还具有允许您扩展现有类的类别,但这些类别不能共享。您必须单独扩展每个类,因此它没有真正的帮助。

是的,您可能对使用类群集感兴趣。这可以生成对象,比如说MyCompositeClass,它将生成MyCompositeScrollClass对象或MyCompositeViewClass对象

苹果经常使用类集群,比如在NSArray中,当你使用它时,在幕后操纵不同的对象。差异取决于数组的大小,例如,对于某些小型数组,NSArray将实例化一个专门用于小型数据结构的类,等等

它的优点是具有良好的性能,并且通过类集群的概念将复杂性完全隐藏在用户面前

我邀请您阅读一些关于这方面的文档,这可能更容易理解。


希望这有帮助:

是的,您可能对使用类集群感兴趣。这可以生成对象,比如说MyCompositeClass,它将生成MyCompositeScrollClass对象或MyCompositeViewClass对象

苹果经常使用类集群,比如在NSArray中,当你使用它时,在幕后操纵不同的对象。差异取决于数组的大小,例如,对于某些小型数组,NSArray将实例化一个专门用于小型数据结构的类,等等

它的优点是具有良好的性能,并且通过类集群的概念将复杂性完全隐藏在用户面前

我邀请您阅读一些关于这方面的文档,这可能更容易理解。


希望这是有帮助的:

当然,最好的方法是从UIView子类继承UIScrollView

@斯帕克斯的回答是好的,但有时授权并不能满足您的要求,或者太不方便了。在这种情况下,可能是后者

考虑在任何地方都将其用作UIScrollView,但要破坏您不需要的功能。UIScrollView实例的行为与UIView实例完全相同—好吧,它们是UIView实例—因此您可以解决这个简单的问题,干扰其中一些实例的操作,然后继续进行。关闭缩放、关闭滚动等

不幸的是,这是单继承语言的现实。无论你做什么,都不要试图通过改变isa来解决这个问题。如果你曾经有过任何成功,它将不会持久。Objective-C只是略微动态的,不允许普通程序员认真使用这种东西
s、 当然,最好的做法是不可能的:从UIView子类继承UIScrollView

@斯帕克斯的回答是好的,但有时授权并不能满足您的要求,或者太不方便了。在这种情况下,可能是后者

考虑在任何地方都将其用作UIScrollView,但要破坏您不需要的功能。UIScrollView实例的行为与UIView实例完全相同—好吧,它们是UIView实例—因此您可以解决这个简单的问题,干扰其中一些实例的操作,然后继续进行。关闭缩放、关闭滚动等


不幸的是,这是单继承语言的现实。无论你做什么,都不要试图通过改变isa来解决这个问题。如果你曾经有过任何成功,它将不会持久。Objective-C只是稍微有点动态,不允许普通程序员认真使用这种东西。

好吧,也许这太疯狂了,但ISA切换是一种选择吗

object->isa = [SomeClass class];
见:

如果您实现的UIView子类知道如何将其ISA指针切换到UIScrollView子类,那么您只需处理一个类,甚至可以在运行时动态决定需要哪些视图

请注意,这纯粹是理论上的。我从来没有在实时代码中使用ISA切换,我个人认为它不适合一个好的设计:P

编辑: 但是,它并没有减少任何冗余。。。
我读了更多关于这个主题的内容,但这似乎并不推荐旧对象的内存结构保持不变,例如。

好吧,也许这太疯狂了,但ISA切换是一个选项吗

object->isa = [SomeClass class];
见:

如果您实现的UIView子类知道如何将其ISA指针切换到UIScrollView子类,那么您只需处理一个类,甚至可以在运行时动态决定需要哪些视图

请注意,这纯粹是理论上的。我从来没有在实时代码中使用ISA切换,我个人认为它不适合一个好的设计:P

编辑: 但是,它并没有减少任何冗余。。。

我读了更多关于这个主题的内容,但它似乎并不推荐旧对象的内存结构保持不变,例如

当UIScrollView已经是UIView的子类时,为什么需要它成为UIScrollView的子类或UIView的子类?需要更多关于您试图完成的内容的详细信息。当UIScrollView已经是UIView的子类时,为什么您需要它成为UIScrollView或UIView的子类?需要更多关于您试图完成的任务的细节。Isa swizzling仅在两个类具有相同的内存布局时才起作用。UIView和UIScrollView不太可能。它们不…UIScrollView的内存更重。Isa swizzling仅在两个类具有相同的内存布局时才起作用。UIView和UIScrollView不太可能。它们不…UIScrollView的内存更大。FWIW,我可能也会先尝试禁用所有UIScrollView内容。也就是说,UISCLVIEW是野兽,我也可以考虑额外的SIMM代码来避免它们,除非我真的需要它们。我认为禁用UISCLVIEW,但事实是,UISCLVIEW增加了一些我不想要的权重。我最初编写复合视图是为了在速度较慢的设备上加速一些动画,它确实做到了这一点。使用UIScrollView会有点失败——虽然不是很多,但已经足够了。@AaronHayman凭经验使用UIScrollView会有点失败吗?我同意它看起来很重,但它是吗?是有点,就像我说的,没什么大不了的。但我在iPad上一次可以在屏幕上看到多达200个视图……在iPhone上可能有50个。总而言之。更糟糕的是,用户可以随意放置。所以,让它尽可能轻是有道理的。@AaronHayman我只是说,如果你还没有尝试1000或2000,也许你会感到惊讶。或许不是;FWIW,我可能也会先尝试禁用所有UIScrollView内容。也就是说,UISCLVIEW是野兽,我也可以考虑额外的SIMM代码来避免它们,除非我真的需要它们。我认为禁用UISCLVIEW,但事实是,UISCLVIEW增加了一些我不想要的权重。我最初编写复合视图是为了在速度较慢的设备上加速一些动画,它确实做到了这一点。使用UIScrollView会有点失败——虽然不是很多,但已经足够了。@AaronHayman凭经验使用UIScrollView会有点失败吗?我同意它看起来很重,但它是吗?是有点,就像我说的,没什么大不了的。但我在iPad上一次可以在屏幕上看到多达200个视图……在iPhone上可能有50个。总而言之。更糟糕的是,用户可以随意放置。所以,让它尽可能轻是有道理的。@AaronHayman我只是说,如果你还没有尝试1000或2000,也许你会感到惊讶。或许不是;是的,实际上这可能是目前为止最好的主意。复合视图实际上使用核心图形来
创建一个UIImage,将其添加到共享缓存中,该缓存由具有相同选项的所有视图共享。视图所做的只是在drawInRect中绘制图像。我可能可以卸下很多。我会让对象创建稍微复杂一点,但这可能是值得的。实际上,UIView上的类别可以工作,但它们不允许属性,因此除非您添加的功能不添加新的状态行为,否则您不能使用它们+1.是的,我并不认为他想添加到所有视图中,所以考虑将category作为mixin应用到从UIView和UIScrollView派生的类中。但是,由于类别本身不能应用于多个类,所以在查看添加ivar内容之前,这一点都不起作用。@smparks一个类别在这个实例中是不起作用的,因为是的,有很多状态需要保存。我认识到,鉴于我所问问题的背景,如果大部分核心图形工作是在DrawRect中完成的,那么您的回答可能不起作用。但事实上,CG工作是在UIGraphicsImageContext中完成的,它很容易导出。所以你的解决方案在我的情况下确实有效。此外,转发方法非常简单。看我的问题:是的,实际上这可能是目前为止最好的主意。复合视图实际上使用核心图形创建UIImage,并将其添加到由具有相同选项的所有视图共享的共享缓存中。视图所做的只是在drawInRect中绘制图像。我可能可以卸下很多。我会让对象创建稍微复杂一点,但这可能是值得的。实际上,UIView上的类别可以工作,但它们不允许属性,因此除非您添加的功能不添加新的状态行为,否则您不能使用它们+1.是的,我并不认为他想添加到所有视图中,所以考虑将category作为mixin应用到从UIView和UIScrollView派生的类中。但是,由于类别本身不能应用于多个类,所以在查看添加ivar内容之前,这一点都不起作用。@smparks一个类别在这个实例中是不起作用的,因为是的,有很多状态需要保存。我认识到,鉴于我所问问题的背景,如果大部分核心图形工作是在DrawRect中完成的,那么您的回答可能不起作用。但事实上,CG工作是在UIGraphicsImageContext中完成的,它很容易导出。所以你的解决方案在我的情况下确实有效。此外,转发方法非常简单。看我的问题:我不知道谁把-1。。。但如果他或她能详细说明,我很想知道我的错误在哪里…我不知道谁把-1。。。但如果他或她能详细说明,我很想知道我的错误在哪里。。