2011-08-26 54 views
0

我已經開始更多地使用委託,就像我提出的另一個問題所建議的那樣。現在,我創建了一個名爲ProfileViewController的UIViewController,我想從Facebook加載新聞Feed。我也有NSObject的子類叫做FBFeed。這個子類加載Facebook News Feed,並將其傳遞迴視圖控制器。我對Facebook的所有要求都是通過一個名爲FBRequestWrapper的單身人士發送的,在這種情況下,應將結果傳遞給FBFeed自定義代理不工作

我打電話getFBRequestWithGraphPath:andDelegate:FBRequestWrapper這將調用Facebook iOS SDK中的一個方法,它將委託作爲參數。如果我放入self(這將是FBRequestWrapper),它工作得很好。如果我輸入_delegate(這是FBFeed的一個實例),則應用程序將崩潰EXC_BAD_ACCESS

我有一個理論爲什麼它可能會崩潰。我已閱讀,

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

應該

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

但這樣做時,我得到了以下錯誤:

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

另外,我不知道這是否足以讓應用程序崩潰

這是我的代碼。

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 
+0

您能說出「EXC_BAD_ACCESS」發生什麼行嗎? – Dani

+0

@Dani,我在使用斷點工具時非常糟糕,但好像它在'ProfileViewController.m'中似乎獲得了傳遞'getFBRequestWithGraphPath:andDelegate:'和'[self loadFeed]'的崩潰(這行應該在調用之前調用'getFBRequestWithGraphPath:AndDelegate'但如前所述,我不善於使用調試工具)。當應用程序崩潰時''main.m'中的'UIApplicationMain(argc,argv,nil,NSStringFromClass([AppDelegate class]));'會突出顯示。 – simonbs

+0

這聽起來似乎合理,錯誤mgiht發生在Facebook iOS SDK內?雖然,當我解析它'self'('FBRequestWrapper')時,它工作正常。這是'FBFeed'是它崩潰的委託。 – simonbs

回答

8

我猜你正在使用ARC和新的iOS5 SDK是仍然在NDA之下。而不是使用保留,使用關鍵字'強'。使用strong將具有與使用retain相同的行爲。設置你的財產是這樣的:

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

+0

啊,當然。這使得'現有伊娃'代表'錯誤消失,但不幸的是應用程序仍然崩潰。 – simonbs

+0

@Suhail Patel:如果任何支付蘋果100美元的人都能夠獲得「NDA」sdk,我不確定NDA將持有多少,以及它是否意味着什麼。 – Dani

1

我覺得有你有兩種方式:

  1. 不要使用ARC,並留下您的代碼,因爲它是

  2. 如果你想使用ARC,請注意委託人通常不應被保留。但是,使用ARC,伊娃的聲明是這樣的時候:

id <FBFeedDelegate> delegate

默認爲

id <FBFeedDelegate> __strong delegate 

所以,當你宣佈這樣的特性:

@property (readwrite, unsafe_unretained) id <FBFeedDelegate> delegate 

伊娃應該看起來像這樣:

id <FBFeedDelegate> __unsafe_unretained delegate 
+0

順便說一句,我會推薦使用ARC,因爲它帶來了一些很大的優勢,比如代碼少,因此減少了錯誤(特別是導致崩潰的內存管理錯誤)和更好的性能 –

+0

+ 1爲ARC概念 – RayofHope

0

我有同樣的問題,但後來才知道是能夠使它的iOS 5.1下正常工作,上了XCode 4.3.2

使用此代碼在您的.h文件中

@protocol AnimationManagerCountdownTimerDelegate <NSObject> 
@required 
    -(void)countdownCompleted; 

@end 


@interface AnimationManager : NSObject{ 
.... 
} 

@property (nonatomic, strong) id <AnimationManagerCountdownTimerDelegate> countdownTimerDelegate; 

@end 

然後在.m文件,您只需簡單地合成:

@synthesize countdownTimerDelegate;