Потоки Objective-C с подклассом NSobject

Я использую класс потоковой передачи (.h/.m ниже), где подкласс UIViewcontroller работает без каких-либо проблем.

@interface myFirstClass : UIViewController <MyOperationDelegate>{

Однако, когда я использую его, где подкласс является NSobject для вызова класса достижимости, проверяющего подключение к Интернету, приложение аварийно завершает работу при вызове executeSelectorOnMainThread? Я не понимаю, почему, когда я создаю приложение, нет ошибок, и когда оно падает, все, что я получаю, это 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 

person david-l    schedule 22.07.2011    source источник
comment
при вызове следующего [self.delegate PerformSelectorOnMainThread:@selector(updatedStatus:) withObject:[NSArray arrayWithObjects:rssItems, nil] waitUntilDone:NO]   -  person david-l    schedule 22.07.2011


Ответы (1)


Проблема в этих строках:

NSMutableArray *rssItems;

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

Вы объявляете переменную rssItems, но не устанавливаете ее. Он будет содержать случайный мусор из стека, который затем будет интерпретирован как указатель. Возможно, иногда вам повезло, и значение на самом деле является указателем на живой объект, но, скорее всего, его разыменование приведет к сбою.

Вам нужно фактически инициализировать переменную, например:

NSMutableArray *rssItems = nil;

но я думаю, вы действительно хотите:

NSMutableArray *rssItems = [NSMutableArray array];
person DarkDust    schedule 22.07.2011
comment
какая глупая ошибка. Мне даже это не нужно, я был слишком увлечен тем, чтобы заставить поток работать, прежде чем добавить правильный логин на место, и просто пропустил это. Спасибо за вашу помощь и время. - person david-l; 22.07.2011
comment
Без проблем. Кстати, статический анализатор должен был предупредить вас об этом. Отличный инструмент. - person DarkDust; 22.07.2011
comment
Я все еще новичок во всем этом, поэтому я учусь каждый день. Я почти никогда не использую анализатор, но я обязательно буду делать это с этого момента, когда я не получаю никакой информации об ошибке. Спасибо за чаевые. - person david-l; 22.07.2011
comment
Надеюсь, вы не возражаете, что я вернусь к вам по этому поводу. Кажется, все работает на симуляторе, даже на iPad, и при сборке не отображаются ошибки/предупреждения. Но в файле .h appController я получаю не могу найти объявление протокола для MyOperationDelegate в этой строке @interface AppController : NSObject ‹MyOperationDelegate›{. Те же ошибки отображаются на myThreading.h в ‹MyOperationDelegate›. Любые идеи? - person david-l; 22.07.2011
comment
Вам нужно #import заголовочный файл, в котором определено @protocol MyOperationDelegate. - person DarkDust; 22.07.2011
comment
У меня это уже есть. Как очень странно. В любом случае, спасибо еще раз. - person david-l; 23.07.2011