【问题标题】:Protocols and delegates are not working properly协议和委托无法正常工作
【发布时间】:2012-03-30 03:00:04
【问题描述】:

我在尝试处理某些事情和现在之间突然出现了这个随机问题。我什至尝试重新加载一个我知道 100% 正常工作的旧快照,但我就是想不出这个废话。

基本上我有一个类和一个视图控制器,该类正在尝试将一些数据传递给视图控制器,该类中的所有内容都运行良好,所有数据都已准备好并等待发送到视图控制器使用我设置的委托和协议,但是当我调试视图控制器时,它永远不会改变我在类中创建的视图控制器中的协议方法。我不知道这是一个简单的错误、疏忽还是我的代码中缺少的东西,我现在将我的代码写下来,希望其他人能看到我缺少的东西。

类.h

//This passes data back to the VehicleSearchViewController
@protocol SearchViewParsedData <NSObject>
- (void)sendManArray:(NSArray *)array;
- (void)sendModArray:(NSArray *)array;
@end
//..
id <SearchViewParsedData> SearchViewdelegate;
//..
//Delegates that will be acessed inside EngineRequests for passing the data mack to the viewcontroller
@property (strong) id <SearchViewParsedData> SearchViewdelegate;
//..

类.m

@synthesize SearchViewdelegate;
//..
//TODO: add if statments in this method so you can pass the data to the right methods and Views
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    if ([methodName isEqualToString:@"GetMan"]) {
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"ISAMAN",@"T"];
    NSArray *filteredArray = [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate];

        NSLog(@"%@", filteredArray);
    [[self SearchViewdelegate]sendMan:filteredArray];
    }
//..

这就是我的课,然后在我的视图控制器中结束

viewcontroller.h

#import "myClass.h"
//..
@interface MyVewController : UITableViewController <SearchViewParsedData> {
//..
MyClass *myClassResponse;
//..

viewcontroller.m

- (void)viewDidLoad
{
    [super viewDidLoad];
//..
engineResponses = [[EngineResponses alloc] init];
[engineResponses setSearchViewdelegate:self];
//..
}


#pragma - EngineResponses Reciver methods
- (void)sendManArray:(NSArray *)array
{
    MyFilterArray = array;
    [self.tableView reloadData]; 
}

这让我有点发疯。我确信我拥有完美的一切,但它只是永远无法到达 viewcontroller.m -(void)sendManArray...如果有人有任何想法,我很想听听。

这是我添加该 nslog 时正在生成的日志

NSLog(@"Checking filtered array %@ %@", [self SearchViewdelegate], filteredArray);

产生:

Checking filtered array (null) (
        {
        ISMAN = F;
        ISVAR = T;
        MAN = "BLAAA";
        MANID = 3;
    },
        {
        ISMAN = F;
        ISVAR = F;
        MAN = "BANG";
        MANID = 3;
    },
//etc

【问题讨论】:

  • 代表传统上是弱的,_unsafe_unretained,或分配,不强。有没有可能 MyFilterArray 没有被分配和初始化?
  • 我正在记录过滤后的数组并在其中显示正确的内容.. 但即使是这种情况,它也不应该出现在我的视图控制器中,并且在该方法中只表示 null .. .
  • 当你这样记录时会发生什么: NSLog(@"%@ %@", [self SearchViewdelegate], filteredArray); ??鉴于您描述的症状,我敢打赌它的 [an array]
  • 我应该把那个 NSLog 放在哪里?别担心,我知道把它放在哪里了.. 现在试试。
  • 好吧.. 很奇怪。你的权利......它有(空)但之后我得到了我想要的xml......但我不知道它来自哪里......我试图找到它,但它就像它的一部分一样打印出来......

标签: iphone ios delegates protocols


【解决方案1】:

我认为您需要将 Class.m 文件替换为以下代码

@synthesize SearchViewdelegate;
//..
//TODO: add if statments in this method so you can pass the data to the right methods and Views
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
     if ([methodName isEqualToString:@"GetMan"]) {
     NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"ISAMAN",@"T"];
     NSArray *filteredArray = [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate];

     NSLog(@"%@", filteredArray);
     [[self SearchViewdelegate]sendManArray:filteredArray];
}

//..

其余一切都是正确的,但我认为 sendMan 不可用(这是在您的代码中编写的)并且在 ViewController 中调用相同的方法

viewcontroller.m

- (void)sendManArray:(NSArray *)array 中替换为以下方法

 - (void)sendManArray:(NSArray *)array
 {
      NSLog(@"%@",array);
 }

【讨论】:

    【解决方案2】:

    你在打电话

    [[self SearchViewdelegate]sendManufactureArray:filteredArray];
    

    但是你的委托方法定义是

    - (void)sendManArray:(NSArray *)array
    

    尝试调用

    [[self SearchViewdelegate]sendManArray:filteredArray];
    

    改为。

    【讨论】:

    • 这仍然是一个错字。它说sendMan,而不是sendManArray
    • 同意,还是错了……你能复制+粘贴代码吗?如果它不是您正在运行的确切代码,则添加它是没有意义的。微小的差异可以决定代码的成败。
    【解决方案3】:

    你可能还有一个错字。在编译时找到它 您可以(暂时)将您的协议定义更改为:

    @protocol SearchViewParsedData <NSObject>
    - (void)sendModArray:(NSArray *)array;
    @required
    - (void)sendManArray:(NSArray *)array;
    @end
    

    也尝试修改你的- (void)parserDidEndDocument:(NSXMLParser *)parser

    - (void)parserDidEndDocument:(NSXMLParser *)parser
    {
        if ([methodName isEqualToString:@"GetMan"])
        {
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"ISAMAN",@"T"];
            NSArray *filteredArray = [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate];
    
            NSLog(@"%@", filteredArray);
            if (!self.SearchViewdelegate)
            {
                if ([self.searchViewdelegate respondsToSelector: @selector(sendManArray:)])
                {
                    NSLog (@"ok, calling my delegate");
                    [[self.searchViewdelegate] sendManArray:filteredArray];
                }
                else
                {
                    NSLog (@"my delegate doesn't implement sendManArray:");
                }
            }
            else
            {
                NSLog (@"i have no delegate");
            }  
        }
        //..
    

    属性名称以大写开头也不是一个好主意 信。不是错误,但您确实应该考虑将 SearchViewdelegate 重命名为 searchViewdelegate

    您也没有向我们展示您的parsedDataArrayOfDictionaries 代码,但您可能会考虑更改:

    NSArray *filteredArray = [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate];
    

    到:

    NSArray *filteredArray = [NSArray arrayWithArray: [parsedDataArrayOfDictionaries filteredArrayUsingPredicate:predicate]];
    

    【讨论】:

    • 好的,所以我已经实现了您在上面显示的 if 语句,并且我得到 my delegate doesn't implement sendManArray: 响应...我也切换了我的过滤数组到上面建议的数组。我还添加了@requiered,但没有发生任何事情。
    • @C.Johns:好的,现在你知道问题出在哪里了。由于您发布的代码包含此拼写错误,我的第一个猜测是您的原始代码也包含此错误。我会逐个字符地检查委托方法名称。
    • 如何实现 sendManArray?我已经在 .h 中初始化了它,就像 id SearchViewdelegate; 并且还 @synthesized 它.. 我还能做什么?
    • 我已经修复了名称中的任何差异,没有我没有收到任何错误。它只是没有正确实施。
    • 是的,奇怪的是它工作得非常好,然后苹果提示我更新我的 xcodes 调试器。从那时起,xcode 出现了很多问题。每当我尝试运行模拟器时,它都会崩溃 xcode,所以我必须构建到我的手机等。我在想这可能是我遇到的问题的延伸,因为它正在工作,然后所有突然停止工作..
    【解决方案4】:

    您的EngineResponses 类是NSXMLParser 的代表。您尝试通过NSXMLParser 委托方法向您的SearchViewdelegate 发送消息(顺便说一句,该拼写是怎么回事?),属性为nil。所以唯一的结论是你在你的NSXMLParser上调用了parse方法之后设置了属性。

    所以我的建议是将委托作为参数传递给您的init 方法,并在发送[NSXLMParser parse] 消息之前设置SearchViewdelegate 属性。

    【讨论】:

      【解决方案5】:

      所以这太疯狂了。我已经解决了这个错误,它与我的代表声明等完全无关。

      上周,xcode 提示我更新调试器,这最终破坏了我的模拟器,或者在尝试部署到模拟器时至少破坏了 xcode。继续我无法解决这个问题,至少直到今天。我在方案设置中恢复了我的旧调试器,所以我从 LLDB 回到了 GDB。这修复了我的模拟器错误和......我的协议委托不起作用......

      什么鬼??? 希望这可以解决其他人的问题.. 真是太痛苦了。

      但是现在我想知道为什么 LLDB 会导致这些问题?如果你能回答那我就给你我提供的声望点:)

      【讨论】:

      • 问题很可能仍然是您的代表声明。强烈的代表不能再错了。
      • 那么应该怎么声明呢?
      • 弱。 Strong 将保留变量。
      • 我同意山姆。应将委托声明为弱或 __unsafe_unretained。将委托声明为强委托会为您设置保留周期和内存泄漏。不过,这不会导致您描述的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-13
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      相关资源
      最近更新 更多