Ios 避免在不向UIViewController添加属性/iVar的情况下释放对象
我有一个自定义类/对象,它使用CADisplayLink处理给定视图的手势和动画。我的类的最简单形式如下所示:Ios 避免在不向UIViewController添加属性/iVar的情况下释放对象,ios,objective-c,dealloc,Ios,Objective C,Dealloc,我有一个自定义类/对象,它使用CADisplayLink处理给定视图的手势和动画。我的类的最简单形式如下所示: @interface SomeClass : NSObject @property (strong) UIView *someView; @end 将以下代码添加到视图控制器时 - (void)viewDidLoad { [super viewDidLoad]; SomeClass *someClass = [[SomeClass alloc] init];
@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)来克服释放,但是我希望在理想情况下避免这种额外的工作
那么,在解除分配与其关联的视图或视图控制器之前,是否仍可以保留我的类
编辑
UIGestureRecognitor对象是一个类的exmaple,当我将它们与视图关联时,它不会被释放
- (void)viewDidLoad
{
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] init];
[someView addGestureRecognizer:gestureRecognizer];
}
// tapGestureRecognizer still lives
这大概是因为UIView拥有UIGestureRecognitor对象的所有权。在我的类和UIView类别中是否有实现这一点的方法?即
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClass = [[SomeClass alloc] init];
[someView addSomeClass:someClass];
}
但您可以声明SomeClass实例,而不是如下所示的属性:
@implementation ViewController
{
SomeClass* _someClass;
}
...
- (void)viewDidLoad
{
[super viewDidLoad];
_someClass = [[SomeClass alloc] init];
_someClass.someView = someView;
}
您的
SomeClass
实例持有对someView
的强引用,但是除了viewDidLoad
消息中的局部变量外,没有任何东西持有对SomeClass
实例的引用,因此只要方法退出,就可以解除分配该实例。由于该对象是对您的UIView
的唯一引用,因此也可以取消分配该视图
您唯一的选择是按照stosha的建议将对SomeClass
对象的引用存储在实例变量(或iVar)或属性中。属性是首选方法,通过自动合成,它们不会比局部变量声明花费更多的精力
您可以在.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;
}
如果您希望以UIGestureRecognitor相同的方式将对象与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
从NSHipster进一步阅读关联对象
道歉,应该特别提到财产或iVar(我认为这是显而易见的)。这正是我想要避免的。谢谢你提供的信息性评论,但是这并不能回答我的问题。好的,那么简短的回答是“不”。是的,您可以修改视图以保存引用,但与简单的PropertyTanks相比,它似乎不必要地复杂,无法实际回答问题。
- (void)viewDidLoad
{
[super viewDidLoad];
SomeClass *someClass = [[SomeClass alloc] init];
someClass.someView = someView;
[someView addSomeClass:someClass];
}