2014-03-26 63 views
2

使用委託我已經得到了想要使用CLLocationManager和它的一些委託方法一類方法。類方法,Objective-C的

什麼是訪問從類方法的委託方法的最佳方式,因爲我沒有真正的實例級別的「自我」?我可以實例化一個自我,作爲委託,這將讓委託方法運行,但沒有說明如何獲取數據出來使用。什麼是最好的方法?

// 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); 
    } 
} 
+0

「這行不通」什麼「不工作」呢? – newacct

+0

在類方法中,我不能沒有得到一個大約兼容的指針類型從類分配委派警告分配「自我」的委託。這是一個好點,它不是一個錯誤,但可以使我的工作意識到。儘管如此,我更喜歡下面解決方案的佈局,因爲我仍然可以訪問類中定義的實例變量,而不需要靜態變量。 – Miro

+0

這是一個警告,因爲類對象名義上沒有實現協議。您可以通過投射到'id':'=(id)self'來擺脫警告。從概念上講,兩者並沒有太大區別,只是在這種情況下,您將類對象本身用作委託而不是某個實例,從而節省了創建另一個對象的必要性。 – newacct

回答

12

我會重做你在做什麼,不要使用類方法。相反,使用一個共享的情況下單,這將讓你幾乎相同寫你的代碼,但給你一個實例一起工作,因此存儲變量和分配代表。

萬一你不熟悉的語法:

+ (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]; 
} 

不過我一般不建議這樣做,因爲你是不是節省了大量的代碼,並在未來將可能出現的混亂,以什麼樣的方法這實際上是從調用方的角度。

+0

這確實得到[[SFGeoPoint實例] geoPoint ...],但仍然希望獲得更簡單的[SFGeoPoint getPoint ...]。 – Miro

+0

我編輯了我的答案,添加了一種方法來執行您要求的操作,只需在實例方法中添加類包裝方法。這很簡單,最有可能是最好的解決方案。 – Dima

+1

非常簡單的最後一點,單身人士也很好。 – Miro