自定义委托不工作 [英] Custom delegate not working

查看:173
本文介绍了自定义委托不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我提出的另一个问题,我已经开始与代表合作了。现在,我已经创建了一个名为 ProfileViewController 的UIViewController,其中我想从Facebook加载新闻源。我也有NSObject的子类名为 FBFeed 。该子类加载Facebook新闻源,并将其传递给视图控制器。所有我对Facebook的请求都是通过一个名为 FBRequestWrapper 的单例发送的(在这种情况下)应该将结果传递给 FBFeed



我在中调用 getFBRequestWithGraphPath:andDelegate: FBRequestWrapper 这将在Facebook iOS SDK中调用方法,该方法将委托作为参数。如果我放入 self (这将是FBRequestWrapper),它的工作原理很好。如果我放入 _delegate (这是 FBFeed 的一个实例),应用程序会崩溃与 EXC_BAD_ACCESS



我有一个理论为什么会崩溃。我读过

  @property(nonatomic,retain)id< FBFeedDelegate>代表; 

应该是

 code> @property(nonatomic,assign)id< FBFeedDelegate>代表; 

但是当这样做时,我会收到以下错误:


对于unsafe_unretained属性'代理'的现有ivar'delegate'
必须为__unsafe_unretained


另外,我不知道是否足够使应用程序崩溃。



这是我的代码。



ProfileViewController.h

  #import< UIKit / UIKit.h> 
#importFeedTableView.h
#importFBFeed.h

@interface ProfileViewController:UIViewController< FBFeedDelegate>
{
FeedTableView * tableView;
}

- (void)loadFeed;

@end

ProfileViewController.m / p>

  @implementation ProfileViewController 

- (void)loadFeed
{
FBFeed * feed = [[FBFeed alloc] init];
[feed loadNewsFeedWithDelegate:self];
}

#pragma mark -
#pragma FBFeedDelegate

- (void)finishedLoadingFeed:(FBFeed *)_ feed
{
NSLog(@ProfileViewController:FBFeed完成);
}

- (void)failedToLoadFeed:(FBFeed *)_ feed
{
NSLog(@ProfileViewController:FBFeed Failed。
}

- (void)viewDidLoad
{
[super viewDidLoad];

//加载Feed
[self loadFeed];
}

@end

FBFeed.h

  #import< Foundation / Foundation.h> 
#importFBRequestWrapper.h

@protocol FBFeedDelegate;

@interface FBFeed:NSObject< FBRequestDelegate>
{
id< FBFeedDelegate>代表;
}

@property(nonatomic,retain)id< FBFeedDelegate>代表;

- (void)loadNewsFeedWithDelegate:(id)_delegate;

@end


@protocol FBFeedDelegate< NSObject>
@required
- (void)finishedLoadingFeed:(FBFeed *)_ feed;
- (void)failedToLoadFeed:(FBFeed *)_ feed;
@end

FBFeed.m

  #importFBFeed.h

@implementation FBFeed

@synthesize delegate;

- (void)loadNewsFeedWithDelegate:(id)_delegate
{
self.delegate = _delegate;

[[FBRequestWrapper defaultManager] getFBRequestWithGraphPath:@meandDelegate:self];


#pragma mark -
#pragma mark FBRequest代理

- (void)请求:(FBRequest *)请求didLoad:(id)结果
{
NSLog(@FBFeed:FBRequest已加载);
NSLog(@%@,result);


- (void)请求:( FBRequest *)请求didFailWithError:(NSError *)错误
{
NSLog(@FBFeed:FBRequest Failed。 );
NSLog(@%@,错误);
}

@end

FBRequestWrapper.h

  #import< Foundation / Foundation.h> 
#importFBConnect.h

@interface FBRequestWrapper:NSObject< FBRequestDelegate,FBSessionDelegate>
{
Facebook * facebook;
BOOL isLoggedIn;
}

@property(nonatomic,assign)BOOL isLoggedIn;

+(id)defaultManager;
- (void)setIsLoggedIn:(BOOL)_loggedIn;
- (void)FBSessionBegin:(id< FBSessionDelegate>)_ delegate;
- (void)FBLogout;
- (void)getFBRequestWithGraphPath:(NSString *)_ path andDelegate:(id)_delegate;
- (void)getFBRequestWithMethodName:(NSString *)_ methodName和Params:(NSMutableDictionary *)_ params andDelegate:(id)_delegate;

@end

FBRequestWrapper.m / p>

  #importFBRequestWrapper.h

static FBRequestWrapper * defaultWrapper = nil;

@implementation FBRequestWrapper
@synthesize isLoggedIn;

+(id)defaultManager
{
if(!defaultWrapper)
{
defaultWrapper = [[FBRequestWrapper alloc] init];
}

return defaultWrapper;
}

- (void)getFBRequestWithGraphPath:(NSString *)_ path andDelegate:(id)_delegate
{
if(_path!= nil)
{
[[UIApplication sharedApplication] setNetworkActivityIndi​​catorVisible:YES];

if(_delegate == nil)
{
_delegate = self;
}

[facebook requestWithGraphPath:_path andDelegate:_delegate];
}
}

#pragma mark -
#pragma mark FBRequestDelegate

- (void)request:(FBRequest *)request didLoad :(id)result
{
[[UIApplication sharedApplication] setNetworkActivityIndi​​catorVisible:NO];
NSLog(@%@,result);


- (void)请求:(FBRequest *)请求didFailWithError:(NSError *)错误
{
[[UIApplication sharedApplication] setNetworkActivityIndi​​catorVisible:NO];
NSLog(@FBRequest Failed:%@,error);
}

@end


解决方案

我想你正在使用ARC和仍在NDA下的新iOS5 SDK。而不是使用retain,请使用关键字strong。使用strong将具有与使用retain相同的行为。设置你的财产如下:



@property(nonatomic,strong)id< FBFeedDelegate>代表;


I have started working more with delegate as suggested in another question I made. Now, I have made a UIViewController called ProfileViewController in which I would like to load the News Feed from Facebook. I also have subclass of NSObject called FBFeed. This subclass loads the Facebook News Feed and should pass it back to the view controller. All my requests to Facebook are sent through a singleton named FBRequestWrapper which (in this case) should pass the result to FBFeed.

I call getFBRequestWithGraphPath:andDelegate: in FBRequestWrapper which will call a method in the Facebook iOS SDK which takes a delegate as a parameter. If I put in self (which will be the FBRequestWrapper) it works just fine. If I put in _delegate (which is an instance of FBFeed) the application crashes with EXC_BAD_ACCESS.

I have a theory why it might crash. I have read that

@property (nonatomic, retain) id <FBFeedDelegate> delegate;

should be

@property (nonatomic, assign) id <FBFeedDelegate> delegate;

But when doing so I get the following error:

Existing ivar 'delegate' for unsafe_unretained property 'delegate' must be __unsafe_unretained

Also, I don't know if that enough to make the application crash.

Here is my code.

ProfileViewController.h

#import <UIKit/UIKit.h>
#import "FeedTableView.h"
#import "FBFeed.h"

@interface ProfileViewController : UIViewController <FBFeedDelegate>
{
    FeedTableView *tableView;
}

- (void)loadFeed;

@end

ProfileViewController.m

@implementation ProfileViewController

- (void)loadFeed
{
    FBFeed *feed = [[FBFeed alloc] init];
    [feed loadNewsFeedWithDelegate:self];
}

#pragma mark -
#pragma FBFeedDelegate

- (void)finishedLoadingFeed:(FBFeed *)_feed
{
    NSLog(@"ProfileViewController: FBFeed Finished.");
}

- (void)failedToLoadFeed:(FBFeed *)_feed
{
    NSLog(@"ProfileViewController: FBFeed Failed.");
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Load feed
    [self loadFeed];
}

@end

FBFeed.h

#import <Foundation/Foundation.h>
#import "FBRequestWrapper.h"

@protocol FBFeedDelegate;

@interface FBFeed : NSObject <FBRequestDelegate>
{
    id <FBFeedDelegate> delegate;
}

@property (nonatomic, retain) id <FBFeedDelegate> delegate;

- (void)loadNewsFeedWithDelegate:(id)_delegate;

@end


@protocol FBFeedDelegate <NSObject>
@required
- (void)finishedLoadingFeed:(FBFeed *)_feed;
- (void)failedToLoadFeed:(FBFeed *)_feed;
@end

FBFeed.m

#import "FBFeed.h"

@implementation FBFeed

@synthesize delegate;

- (void)loadNewsFeedWithDelegate:(id)_delegate
{
    self.delegate = _delegate;

    [[FBRequestWrapper defaultManager] getFBRequestWithGraphPath:@"me" andDelegate:self];
}

#pragma mark -
#pragma mark FBRequest Delegate

- (void)request:(FBRequest *)request didLoad:(id)result
{
    NSLog(@"FBFeed: FBRequest Did Load.");
    NSLog(@"%@", result);
}

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
    NSLog(@"FBFeed: FBRequest Failed.");
    NSLog(@"%@", error);
}

@end

FBRequestWrapper.h

#import <Foundation/Foundation.h>
#import "FBConnect.h"

@interface FBRequestWrapper : NSObject <FBRequestDelegate, FBSessionDelegate>
{
    Facebook *facebook;
    BOOL isLoggedIn;
}

@property (nonatomic, assign) BOOL isLoggedIn;

+ (id)defaultManager;
- (void)setIsLoggedIn:(BOOL)_loggedIn;
- (void)FBSessionBegin:(id<FBSessionDelegate>)_delegate;
- (void)FBLogout;
- (void)getFBRequestWithGraphPath:(NSString *)_path andDelegate:(id)_delegate;
- (void)getFBRequestWithMethodName:(NSString *)_methodName andParams:(NSMutableDictionary *)_params andDelegate:(id)_delegate;

@end

FBRequestWrapper.m

#import "FBRequestWrapper.h"

static FBRequestWrapper *defaultWrapper = nil;

@implementation FBRequestWrapper
@synthesize isLoggedIn;

+ (id)defaultManager
{
    if(!defaultWrapper)
    {
        defaultWrapper = [[FBRequestWrapper alloc] init];
    }

    return defaultWrapper;
}

- (void)getFBRequestWithGraphPath:(NSString *)_path andDelegate:(id)_delegate
{
    if (_path != nil)
    {
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

        if (_delegate == nil)
        {
            _delegate = self;
        }

        [facebook requestWithGraphPath:_path andDelegate:_delegate];
    }
}

#pragma mark -
#pragma mark FBRequestDelegate

- (void)request:(FBRequest *)request didLoad:(id)result
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    NSLog(@"%@", result);
}

- (void)request:(FBRequest *)request didFailWithError:(NSError *)error
{
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    NSLog(@"FBRequest Failed: %@", error);
}

@end

解决方案

I guess you are using ARC and the new iOS5 SDK which is still under NDA. Instead of using retain, use the Keyword 'strong'. Using strong will have the same behaviour intended as using retain. Set up your property like this:

@property (nonatomic, strong) id <FBFeedDelegate> delegate;

这篇关于自定义委托不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆