在我正在编写的iOS应用程序中,我们有一个非常常见的“添加照片”按钮 - 按下时,向用户显示一张动作表,可以拍摄或选择照片,转到相机或照片库,然后返回到控制器。选择图像后,它会被调整大小并设置为点击的原始按钮的背景。
为了帮助清理,我决定将大量此功能放在自定义按钮AddPhotoButton
中。当点击按钮时,AddPhotoButton
本身不是处理动作表和图像选择器的控制器。在某些情况下这很好用,但在其他情况下,我遇到了很多内存问题。当相机弹出时,包含该按钮的控制器最终释放它,因此当UIImagePickerController尝试调用委托方法(AddPhotoButton
是其委托)时,该对象不再存在,因为没有任何东西拥有它。
所以,我真正要问的是 - 处理这类事情的最佳方法是什么?我想将照片按钮功能(显示动作表,图像选择器,然后设置背景图像)全部捆绑在一起,因此很容易重复使用,但似乎我采取的方法不正确。但是,也许我正确地做了,但应该以不同的方式保留按钮。
有什么想法吗?
答案 0 :(得分:1)
您尝试这样做的方式通常是避免,因为您通过将逻辑存储在GUI元素的子类中而不必要地将接口绑定到后台逻辑。但是,你所做的一切在技术上都是错误的,听起来它应该有效,你只是处理错误的内存管理。所以我将提供两种可能的解决方案:
修复内存管理 要告诉你如何修复,我将不得不看到一些代码。为什么旧的视图控制器会释放按钮?您是在远离视图控制器还是在顶部添加另一个?
改善班级设计(首选) 您可以创建一个控制器类,而不是将您的逻辑添加到按钮子类。这根本不是视图或任何gui元素。我们称之为“ButtonBackgroundPicker”。这个类将有一个方法,说开始选择一个图像,该图像也采用按钮来改变作为参数的背景。 ButtonBackgroundPicker将处理所有逻辑,完成后,它将设置按钮的背景。所有按钮应该创建ButtonBackgroundPicker并调用该函数来选择一个图像,为它提供一个引用。如果您希望能够为其他类型的UI元素选择背景,则可以在ButtonBackgroundPicker中创建该元素需要实现的协议,以便ButtonBackgroundPicker可以报告选择图像。然后,不是使用函数传递元素,而是将其设置为控制器的委托。
这种设计首选的原因是它不会将gui和逻辑耦合在一起。您可以轻松扩展此设计以与其他UIElements一起使用。使用委托甚至更好,因为您可以使用相同的类和代码来处理关于选择图像的任何事情。