【问题标题】:objective-c protocol delegatesObjective-C 协议委托
【发布时间】:2011-09-06 01:22:22
【问题描述】:

我正在了解委托的工作原理,已经通过一些示例,但现在有了一个用于测试的基本应用程序,似乎我还没有得到它,

这是我的代码:

类定义协议> *.h

#import <Foundation/Foundation.h>
@protocol protoPerra <NSObject>

-(void) dimeTuNombre:(NSString *) s;
@end

@interface MyClassic : NSObject {
id<protoPerra> _delegate;  
}
@property (assign) id<protoPerra> delegate;
@end

类实现协议> *.m

#import "MyClassic.h"

@implementation MyClassic
@synthesize delegate = _delegate;
- (id)init
{
self = [super init];
if (self) {
    // Initialization code here.
    [[self delegate] dimeTuNombre:@"pinguete"];
 }

return self;
}
-(void) dealloc {
[_delegate release];
_delegate = nil;
[super dealloc];
}
@end

类采用协议:

#import "MyClassic.h" @interface MainViewController : UIViewController (protoPerra)

.m

#import "MainViewController.h"
  @implementation MainViewController
  -(void) dimeTuNombre {
   NSLog(@"ss9!! tkt");
   }
   - (void)viewDidLoad {
[super viewDidLoad];

UILabel *lava = [[[UILabel alloc] initWithFrame:CGRectMake(30, 100, 100, 20)] autorelease];
lava.text = @"lava ss9";
[self.view addSubview:lava];

MyClassic *pirr = [[[MyClassic alloc] init ] autorelease];
[pirr setDelegate:self];
 }
 -(void) dimeTuNombre:(NSString *)s {
   NSLog(@"%@",s);
  }
  @end

那么在这个简单的示例中缺少什么以使其与我的代表一起工作?

非常感谢!

请注意,我使用了 [在收养类的 .h 中] 的 (),就好像我使用雪佛龙一样,代码消失了

【问题讨论】:

    标签: ios delegates protocols


    【解决方案1】:

    您在 MyClassic init 中调用了委托方法 (dimeTuNombre:),但尚未设置委托,因此您需要重新考虑何时调用 dimeTuNombre:,或者将 MyClassic 类重构为具有类似的构造函数

    -(id)initWithDelegate:(id<protoPerra>)delegate
    

    而不仅仅是简单的初始化。

    为了澄清,在您当前的代码中,当您执行 [pirr setDelegate:self]; 时,您在 MainViewController.h 中设置了委托; - 将 MyClassic 属性的值“delegate”设置为 MainViewController 的当前实例。请注意,当您调用 MyClassic 的 init 时,委托尚未设置,因此 [[self delegate] dimeTuNombre:@"pinguete"]; call 什么都不做(此时代表为零)。

    您可以按如下方式更改 MyClassic 构造函数:

    -(id)initWithDelegate:(id<protoPerra>)aDelegate
    {
    self = [super init];
    if (self) {
        _delegate = aDelegate;
        // Initialization code here.
        [[self delegate] dimeTuNombre:@"pinguete"];
     }
    
    return self;
    
    }
    

    然后代替这个:

    MyClassic *pirr = [[[MyClassic alloc] init ] autorelease];
    [pirr setDelegate:self];
    

    你会这样做:

    MyClassic *pirr = [[[MyClassic alloc] initWithDelegate:self ] autorelease];
    

    这可行,但请注意,委托通常用于各种类型的通知 - 例如报告已单击的按钮或表示已收到某些数据的套接字。

    【讨论】:

    • 嗨,感谢您的帮助,但我还不明白为什么没有设置委托?,>[[self delegate] dimeTuNombre:@"pinguete"];没有设置它?或者,我将如何重构 MyClassic 类?谢谢!
    【解决方案2】:

    我认为来自斯坦福大学的Paul Hegarty 在第 9 课,iOS 开发应用程序,2011 年秋季会议(可在 iTunes 中找到,查看 Paul 的博客)中对如何使用协议进行了很好的总结:

    1. 创建@协议
    2. 将委托@property 添加到委托人的公共@interface
    3. 在委托人的实现中使用委托属性
    4. 在委托的@implmentation 中的某处设置委托属性
    5. 在委托中实现协议的方法(包括@interface上的)

    Paul 还举例说明了如何在计算器应用中使用协议。

    首先,创建协议:

    @protocol CalculatorProgramsTableViewControllerDelegate
    
    @optional
    - (void)calculatorProgramsTableViewController:
        (CalculatorPorgramTableViewController *)sender
                                     choseProgram:(id)program;
    @end
    

    步骤 2)。在 CalculatorProgramsTableViewController.h 的表视图中,委托被定义为弱链接 id 属性:

    @interface CalculatorProgramsTableViewController : UITableViewController
    ...
    // Define a property delegate
    @property (nonatomic, weak) id<CalculatorProgramsTableViewControlerDelegate>
                                delegate;
    ...
    @end
    

    通过使用该协议,表格视图将能够发送有关程序更改的消息,但视图不知道图形视图。这将在下一步中完成。

    步骤 3)。在表格视图控制器中,委托用于向外部发送有关程序更改的消息:

    #progma mark - UITableViewDelegate
    - (void)tableView:(UITableView *)tableView
        didSeelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
      id program = [self.programs objectAtIndex:indexPath.row];
      [self.delegate calculatorProgramsTableViewController:self
                                              choseProgram:porgram];
    }
    

    第 4 步)。委托在哪里设置?它在calculatorGraphViewController 中设置(拆分视图中的右视图)。当 segue 准备好推送弹出视图(表格视图)时,它会将 self 设置为委托:

    @implementation CalculatorGraphViewController
    ...
    - (void)prepareForSegue:(UIStoryboardSegue *)segue
                     sender:(id)sender
    {
      if ([segue.identifier isEqualToString:@"Show Favorite Graphics"]) {
        NSArray * programs = [[NSUserDefaults standardUserDefaults]
                             objectForKey:FAVORITES_KEY];
        [segue.destinationViewController setPrograms:programs];
        [segue.destinationViewController setDelegate:self]; // set delegate
      }
    }
    

    图形视图不知道表格视图,通讯通道由协议搭建,完美无耦合!为了让任何委托都能通过此协议进行回调,图形视图控制器的 .h 文件必须实现该协议:

    // .h to implement the protocol
    @interface CalculatorGraphViewController :NSObject 
         <CalculatorProgramsTableViewControllerDelegate>
    ...
    @end
    

    并且protocol的方法在下一步的.m文件中定义。

    最后一步。委托的协议方法在 segue 的控制器中实现。 The protocol's method will be called when a row in table view is selected:

    // implement delegate method
    - (void)calculatorProgramsTableViewController:(CalculatorProgramsTableViewController *)sender
                                    chooseProgram:(id)program
    {
      self.calculatorProgram = program;
    }
    

    以上是iOS应用中协议使用的典型方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2019-12-27
      • 2015-08-14
      • 2010-11-15
      • 1970-01-01
      相关资源
      最近更新 更多