委托模式中的变量丢失值

Variable losing value in delegation pattern

我正在尝试了解 Objective-C 中的委派,但我遇到了一个小问题,即变量在传输过程中丢失了它的数据。我有包含 NSMutableArray 的 Class1。数组被填充,然后我想将数组的值传输到 Class2,并显示它。这是Class1中的相关代码:

 //Class1.h
 @class Class1;
 // define the protocol for the delegate
 @protocol Class1Delegate

 @required
 -(void)sayHello:(Class1 *)customClass withAntArray:(NSMutableArray *)antArray;

 @end

 @interface Class1 : MySuperClassName

 @property (nonatomic, assign) id delegate;

 -(void)helloDelegate;

 @end


    //Class1.m:
@interface Class1 ()
@property (nonatomic, strong) NSMutableArray *antOccurenceTimes;
@end
@implementation Class1
@synthesize antOccurenceTimes;

-(void)helloDelegate
{
    // send the message to the delegate


 [_delegate sayHello:self withAntArray:self.antOccurenceTimes];
}

现在,这是我在 Class2 中的内容:

#import "Class1.h"
@interface Class2 : UIView <Class1Delegate>
@end
// Class2.m:
- (void)appropriateTimeToCallMethod {
    Class1 *initAntMarks = [[Class1 alloc] init];
    initAntMarks.delegate = self;
    [initAntMarks helloDelegate];
}
-(void)sayHello:(Class1 *)customClass withAntArray:(NSMutableArray *)antArray {

    NSLog(@"Hello! %@", antArray.description);
}

antArray.description 读作 "NULL"。现在,我认为它显然将为空,因为我刚刚在调用所需方法之前创建了一个全新的 class 实例。我觉得我可能搞混了,作为代表团的新手,我不确定到底是什么。有谁知道我需要调整什么才能利用委托? 我忘了补充一点,我确实在 Class1 中对其进行了初始化,并且填充得很好。只有在 class2 中才会出现这种情况。

我在下面代码片段中的 ClassA 中用一个单独的方法初始化了 antOccuranceTimes,NSLog 触发了两次...

NSLog(@"Array initalized in class A"); 
antOccurenceTimes = [NSMutableArray new];

您还没有初始化antOccurenceTimes。因为它是零。根据您的需要,有很多选项。例如,您可以在 init 函数中初始化它:

- (instancetype)init {
    self = [super init];
    if( self ) {
        antOccurenceTimes = [NSMutableArray array];
        [antOccurenceTimes addObject:@"Hello World"];
    }
}

或者在调用委托函数之前对其进行初始化。

-(void)helloDelegate
{
    // send the message to the delegate

    self.antOccurenceTimes = [NSMutableArray array]; 
    [self.antOccurenceTimes addObject:@"Hello World"];
    [_delegate sayHello:self withAntArray:self.antOccurenceTimes];
}

我想你明白我的意思了。

更改此行:

@property (nonatomic, assign) id delegate;

至:

@property (nonatomic, weak) id <Class1Delegate> delegate;

assign 应该只用于 C 原语,而不是 Objective-c 对象引用。在向委托发送消息之前,您还应该检查您的对象是否确实符合委托。

编辑:

我想你可能对授权的目的感到困惑。

Class1 *initAntMarks = [[Class1 alloc] init];
initAntMarks.delegate = self;
[initAntMarks helloDelegate];

当您可以简单地创建一个 return 是 NSMutableArray 的方法时,为什么要调用一个对象的方法,而该对象又会调用委托方法?当前设置代码的方式要求在调用 -helloDelegate 之前,您必须用适当的对象填充数组。 MVC 中委托的目的是通知一个对象有关另一个对象内部发生的事件。您正在 "delegating" 将任务交给另一个对象,或者您可以说,另一个对象是否负责完成该任务。阅读Apple Docs on Delegation。代码中的委派不是要实现的正确模式,正如我所说,您可以简单地 return 通过方法调用该数组。

编辑 2:

有两种方法可以实现此目的,通过 属性 方法或通过 return 数组的显式方法。如果您选择使用 属性 方法,则 属性 声明必须在 public 接口中,即 .h 文件中,以便您的 class 可以访问所有访问器该对象正在实施中。

//Inside the .h
@property (nonatomic, strong) NSMutableArray *antOccurenceTimes;

这将自动为您提供 antOccurenceTimes 属性 的两种访问器方法。这些是 getter -antOccurenceTimes 和 setter -setAntOccurenceTimes: 方法。现在,在初始化 class 并填充数组后,您可以调用 -antOccurenceTimes 到 return 数组。

您还可以创建一个显式方法 return 数组:

- (NSMutableArray *)hello{

    //Do something here
    return _antOccurenceTimes;

}