Objective-C 线程与 NSobject 子类
我使用一个线程类(下面的.h/.m),其中子类是 UIViewcontroller 工作没有任何问题。
@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
Im using a threading class (.h/.m below) where the subclass is UIViewcontroller works without any issues.
@interface myFirstClass : UIViewController <MyOperationDelegate>{
However when I use it where the subclass is a NSobject to call a reachability class checking for internet connection, the App crashes when calling performSelectorOnMainThread? I dont understand why, there are no error when I build the App and when it crashes all i get is EXC_BAS_ACCESS. Is it not possible to do this when dealing with an NSObject? Any suggestion will be helpful for me.
@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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于以下几行:
您声明了一个变量 rssItems 但没有设置它。它将包含来自堆栈的随机垃圾,然后将其解释为指针。也许有时你很幸运,该值实际上是一个指向活动对象的指针,但更有可能取消引用它会导致你的崩溃。
您需要实际初始化变量,例如:
但我想您确实想要:
The problem are these lines:
You declare a variable
rssItems
but don't set it. It will contain random garbage from the stack which will then be interpreted as a pointer. Maybe sometimes you're lucky and the value is actually a pointer to a living object, but more likely dereferencing it causes your crash.You need to actually initialize the variable, e.g.:
but I guess you really want: