我有一个自定义类/对象,可以使用CADisplayLink处理手势并为给定视图执行动画。在最简单的形式中,我的类看起来如下:
@interface SomeClass : NSObject
@property (strong) UIView *someView;
@end
当我将以下代码添加到我的视图控制器....
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClass = [[SomeClass alloc] init];
someClass.someView = someView;
}
...我期待我的someClass对象将在视图控制器的生命周期中保留,因为我使用了对someView的强引用。
但是someClass立即被释放。
我已经意识到我可以通过添加someClass作为视图控制器的属性(或实际上是iVar)来克服释放,但我最好还是要避免这些额外的工作......
那么无论如何我可以保留我的班级,直到与其关联的视图或视图控制器被解除分配?
修改
UIGestureRecognizer对象是一个类的例子,当我将它们与视图相关联时,它不会被释放...
- (void)viewDidLoad
{
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
[someView addGestureRecognizer:gestureRecognizer];
}
// tapGestureRecognizer still lives
据推测,这是因为UIView获取了UIGestureRecognizer对象的所有者。无论如何我的班级和UIView类别都能达到这个目的吗?即....
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClass = [[SomeClass alloc] init];
[someView addSomeClass:someClass];
}
答案 0 :(得分:0)
但你可以声明SomeClass实例而不是像这样的属性:
@implementation ViewController
{
SomeClass* _someClass;
}
...
- (void)viewDidLoad
{
[super viewDidLoad];
_someClass = [[SomeClass alloc] init];
_someClass.someView = someView;
}
答案 1 :(得分:0)
您的SomeClass
实例持有对someView
的强引用,但除了SomeClass
消息中的局部变量之外,没有任何内容引用viewDidLoad
实例,因此,只要方法退出,就可以释放该实例。因为那是持有UIView
唯一引用的对象,视图也可以被释放。
您唯一的选择是将实例变量(或iVar)中的SomeClass
对象的引用存储为stosha建议或属性。属性是首选方法,通过自动合成,它们不会比局部变量声明花费更多的精力。
您可以在.m文件中声明该属性,以使其对引用您的ViewController
类的其他类不可见 -
在ViewController.m
文件中 -
@interface ViewController ()
@property (strong, nonatomic) SomeClass *someClass;
@end
@implementation ViewController
...
(void)viewDidLoad
{
[super viewDidLoad];
self.someClass = [[SomeClass alloc] init];
self.someClass.someView = someView;
}
答案 2 :(得分:0)
如果你想以与UIGestureRecognizer相同的方式将对象与UIView相关联,那么使用关联对象可以技术,如下所示(但我不确定我是否会提倡这种方法,因为关联对象经常不赞成)...
<强> SomeClass.h 强>
@class SomeClass;
@interface UIView (SomeClass)
- (void)addSomeClass:(SomeClass *)someClass;
- (void)removeSomeClass:(SomeClass *)someClass;
@end
@interface SomeClass : NSObject
@property (strong) UIView *someView;
@end
<强> SomeClass.m 强>
#import "SomeClass.h"
#import <objc/runtime.h>
@implementation UIView (AssociatedObject)
- (void)addSomeClass:(SomeClass *)someClass
{
NSMutableArray *someClasses = [self someClasses];
if (someClasses == nil) {
someClasses = [[NSMutableArray alloc] init];
[self setSomeClasses:someClasses];
}
[someClasses addObject:someClass];
}
- (void)removeSomeClass:(SomeClass *)someClass
{
NSMutableArray *someClasses = [self someClasses];
if (someClasses != nil) {
[someClasses removeObject:someClass];
if (someClasses.count == 0) {
[self setSomeClasses:nil];
}
}
}
#pragma mark - Private Methods
- (NSMutableArray *)someClasses
{
return (NSMutableArray *)objc_getAssociatedObject(self, @selector(someClasses));
}
- (void)setSomeClasses:(NSMutableArray *)someClasses
{
objc_setAssociatedObject(self, @selector(someClasses), someClasses, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
@implementation SomeClass
@end
实施
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClass = [[SomeClass alloc] init];
someClass.someView = someView;
[someView addSomeClass:someClass];
}
进一步阅读NSHipster的关联对象...