использование делегатов в методе класса, target-c

У меня есть метод класса, который хочет использовать CLLocationManager и некоторые из его методов делегата.

Каков наилучший способ получить доступ к методам делегата из метода класса, поскольку у меня нет истинного уровня экземпляра «я»? Я мог бы создать экземпляр self и использовать его в качестве делегата, что позволит запускать методы делегата, но не покажет, как получить данные. Каков наилучший подход?

// desired end function, which runs a block when location is found
[SFGeoPoint geoPointForCurrentLocationInBackground:^(SFGeoPoint *geoPoint, NSError *error) {
    if (!error) {
        // do something with the new geoPoint
        NSLog(@"GeoPoint: %@", geoPoint);
    }
}];


// SFGeoPoint class, key points
static CLLocationManager *_locationManager = nil;

// get geo point for current location and call block with it
+ (void) geoPointForCurrentLocationInBackground:( void ( ^ )( SFGeoPoint*, NSError* ) ) locationFound {

    SFGeoPoint *point = [[SFGeoPoint alloc] init];

    _locationManager = [[CLLocationManager alloc] init];

    // ?????????
    _locationManager.delegate = self;  // this gives a warning about incompatible pointer type assigning Delegate from Class; 
    _locationManager.delegate = point;  // could work, but how to get feedback?  

    _locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [_locationManager startUpdatingLocation];

    [_locationManager startUpdatingLocation];
    locationFound(point, nil);
}


/////////// Core Location Delegate
+ (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
       fromLocation:(CLLocation *)oldLocation {

    [_locationManager stopUpdatingLocation];

    if (_locationBlock) {
        _locationBlock(newLocation);
    }
}

person Miro    schedule 26.03.2014    source источник
comment
это не работает Что не работает об этом?   -  person newacct    schedule 27.03.2014
comment
В методе класса я не могу назначить себя делегату, не получив предупреждение о несовместимом типе указателя, назначающем делегата из класса. Хорошо, что это не ошибка, и я понимаю, что ее можно заставить работать. Однако я предпочитаю макет решения ниже, так как я все еще могу получить доступ к переменным экземпляра, определенным в классе, вместо того, чтобы нуждаться в статических переменных.   -  person Miro    schedule 27.03.2014
comment
это предупреждение, потому что объект класса номинально не реализует протокол. Вы можете избавиться от предупреждения, приведя к id: = (id)self. Концептуально они не так уж сильно отличаются, просто в этом случае вы используете сам объект класса в качестве делегата вместо некоторого экземпляра, избавляя вас от необходимости создавать другой объект.   -  person newacct    schedule 27.03.2014


Ответы (1)


Я бы переработал то, что вы делаете, и не использовал бы методы класса. Вместо этого используйте синглтон с общим экземпляром, который позволит вам писать код почти идентично, но даст вам экземпляр для работы и, следовательно, для хранения переменных и назначения делегатов.

На всякий случай, если вы не знакомы с синтаксисом:

+ (instancetype) shared
{
    static dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

Затем просто измените все ваши методы + (класса) на методы - (экземпляра) и получите доступ к вашему классу с помощью [[MyClass shared] doWhatever];

изменить с помощью дополнительной оболочки:

Если вы действительно хотите вызвать метод без экземпляра, вы можете написать оболочку, которая будет делать что-то вроде этого:

+ (void) doWhatever
{
    [[self shared] doWhatever];
}

Тем не менее, я обычно не рекомендую делать это, потому что вы не сохраняете много кода и добавляете возможную путаницу в будущем относительно того, какой метод это на самом деле с точки зрения вызывающей стороны.

person Dima    schedule 26.03.2014
comment
Это действительно получает [[экземпляр SFGeoPoint] geoPoint...], но все еще надеется получить более простой [SFGeoPoint getPoint...]. - person Miro; 26.03.2014
comment
Я отредактировал свой ответ, чтобы добавить способ делать то, что вы просите, просто добавив метод обертывания класса вокруг метода экземпляра. Это настолько просто, насколько это возможно, и, скорее всего, это лучшее решение. - person Dima; 27.03.2014
comment
Удивительно простая конечная точка, и синглтон тоже хорошо работает. - person Miro; 27.03.2014
comment
Этот ответ был очень полезен, дал дополнительную награду. - person Miro; 31.03.2014