Objective-C 线程与 NSobject 子类

发布于 2024-11-25 15:37:30 字数 2981 浏览 2 评论 0原文

我使用一个线程类(下面的.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我家小可爱 2024-12-02 15:37:30

问题在于以下几行:

NSMutableArray *rssItems;

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

您声明了一个变量 rssItems 但没有设置它。它将包含来自堆栈的随机垃圾,然后将其解释为指针。也许有时你很幸运,该值实际上是一个指向活动对象的指针,但更有可能取消引用它会导致你的崩溃。

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

NSMutableArray *rssItems = nil;

但我想您确实想要:

NSMutableArray *rssItems = [NSMutableArray array];

The problem are these lines:

NSMutableArray *rssItems;

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

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.:

NSMutableArray *rssItems = nil;

but I guess you really want:

NSMutableArray *rssItems = [NSMutableArray array];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文