Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 避免在不向UIViewController添加属性/iVar的情况下释放对象_Ios_Objective C_Dealloc - Fatal编程技术网

Ios 避免在不向UIViewController添加属性/iVar的情况下释放对象

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];

我有一个自定义类/对象,它使用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)来克服释放,但是我希望在理想情况下避免这种额外的工作

那么,在解除分配与其关联的视图或视图控制器之前,是否仍可以保留我的类

编辑

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];
}