2011-07-22 38 views
0

使用线程类(.h/.m以下)的地方,其中子类是UIViewcontroller,没有任何问题。使用NSobject子类的objective-c线程

@interface myFirstClass : UIViewController <MyOperationDelegate>{ 

然而,当我使用它在子类是NSObject的调用类的可达性检查互联网连接,调用performSelectorOnMainThread当应用程序崩溃?我不明白为什么,当我构建应用程序时,没有错误,当它崩溃时,我得到的是EXC_BAS_ACCESS。处理NSObject时不可能做到这一点?任何建议都会对我有所帮助。

@interface AppController : NSObject <MyOperationDelegate>{ 

myThreading.h

@protocol MyOperationDelegate 
    @required 
    -(void) updatedStatus:(NSArray*)items; 
    -(void) failedStatusWithError:(NSError*)error; 
@end 

@interface MyOperation : NSObject {  
    NSObject<MyOperationDelegate> * delegate; 
    NSOperationQueue *queue; 
} 

@property (retain) NSObject<MyOperationDelegate> *delegate; 

-(void)load: (NSString *)stringUrlPath:(NSString *)functionAction; 

@end 

myThreading.m

@interface MyOperation (NSObject) 
    -(void)dispatchLoadingOperation:(NSDictionary *)aParameters;   
@end 


@implementation MyOperation 

@synthesize delegate; 

-(id)init 
{ 
    if ([super init]!=nil) { 
     queue = [NSOperationQueue new]; 
     [queue setMaxConcurrentOperationCount:1]; 
    } 
    return self; 
} 

-(void)load: (NSString *)stringUrlPath: (NSString *)functionAction { 

    [self dispatchLoadingOperation:[NSDictionary dictionaryWithObjectsAndKeys: 
             stringUrlPath, @"urlString", functionAction, @"action", nil]]; 
} 

-(void)dealloc { 
     [queue cancelAllOperations]; 
     self.delegate = nil; 
     [super dealloc]; 
} 

-(void)dispatchLoadingOperation:(NSDictionary *)aParameters { 

    if([aParameters objectForKey:@"action"] == @"getStatus"){ 
     @synchronized(self) { 
      NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self 
                         selector:@selector(fetchCheckStatus:) 
                          object:aParameters]; 
      [queue addOperation:operation]; 
      [operation release]; 
     } 
    } 
} 


-(void) fetchCheckStatus:(NSDictionary *)aParameters 
{ 

    NSData* data = [[NSMutableData alloc] initWithContentsOfURL:[NSURL URLWithString:[aParameters objectForKey:@"urlString"]] ]; 

    NSError *error; 
    NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

    if (responseString != nil) { 

     NSMutableArray *rssItems; 

     [self.delegate performSelectorOnMainThread:@selector(updatedStatus:) withObject:[NSArray arrayWithObjects:rssItems, nil] waitUntilDone:NO]; 


    } else { 
      [queue cancelAllOperations]; 
      [self.delegate performSelectorOnMainThread:@selector(failedStatusWithError:) withObject:error waitUntilDone:NO]; 
    } 

    [responseString autorelease]; 
    [data release]; 
} 
@end 
+0

它在哪里崩溃? – DarkDust

+0

当它调用以下** [self.delegate performSelectorOnMainThread:@selector(updatedStatus :) withObject:[NSArray arrayWithObjects:rssItems,nil] waitUntilDone:NO] ** –

回答

0

的问题是这些线路:

NSMutableArray *rssItems; 

[self.delegate performSelectorOnMainThread:@selector(updatedStatus:) withObject:[NSArray arrayWithObjects:rssItems, nil] waitUntilDone:NO]; 

声明变量rssItems,但不设置它。它将包含堆栈中的随机垃圾,然后将其解释为指针。也许有时候你很幸运,价值实际上是指向活着的物体的指针,但更有可能解引用它会导致你的崩溃。

实际上你需要初始化变量,例如:

NSMutableArray *rssItems = nil; 

,但我猜你真的想:

NSMutableArray *rssItems = [NSMutableArray array]; 
+0

什么是一个愚蠢的错误。我甚至不需要这样做,我只能专注于在将正确的登录名添加到位之前进行流程工作,并忽略它。感谢您的帮助和时间。 –

+0

没问题。顺便说一句,静态分析仪应该已经警告过你。伟大的工具。 – DarkDust

+0

我仍然是所有这些东西的新手,所以每天都在学习。我几乎没有使用过分析仪,但是当我从错误中获取任何信息时,都不能确保从现在开始。谢谢你的提示。 –