在课堂上使用委托方法,objective-c

在课堂上使用委托方法,objective-c,objective-c,delegates,block,class-method,Objective C,Delegates,Block,Class Method,我有一个类方法想要使用CLLocationManager及其一些委托方法 既然我没有真正的实例级别“self”,那么从类方法访问委托方法的最佳方式是什么?我可以实例化一个self并将其用作委托,这样可以让委托方法运行,但不会显示如何获取数据。最好的方法是什么 // desired end function, which runs a block when location is found [SFGeoPoint geoPointForCurrentLocationInBackground:^(

我有一个类方法想要使用CLLocationManager及其一些委托方法

既然我没有真正的实例级别“self”,那么从类方法访问委托方法的最佳方式是什么?我可以实例化一个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);
    }
}

我会重做您正在做的事情,而不使用类方法。取而代之的是,使用共享实例单例,这将允许您以几乎相同的方式编写代码,但会为您提供一个可使用的实例,从而存储变量并分配委托

以防您不熟悉语法:

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

也就是说,我一般不建议这样做,因为这样做不会节省太多代码,而且将来可能会对调用方的观点造成混淆。

这确实得到了[[SFGeoPoint instance]geoPoint…],但仍然希望得到更简单的[SFGeoPoint getPoint…]我编辑了我的答案,添加了一种方法来完成你的要求,只需在实例方法周围添加一个类包装方法。这很简单,很可能是最好的解决方案。令人惊讶的简单的最后一点,单例也很好。这个答案非常有用,给了额外的奖励。“这不起作用”什么“不起作用”?在课堂方法中,我不能分配“自我”在没有得到关于从类中分配委托的指针类型不兼容的警告的情况下,将该委托。这是一个很好的观点,它不是一个错误,虽然,可以使工作,我意识到。不过,我更喜欢下面解决方案的布局,因为我仍然可以访问类中定义的实例变量,而不需要静态变量。这是一个警告,因为类对象名义上并不实现协议。您可以通过强制转换到
id
=(id)self
来消除警告。从概念上讲,这两者没有太大区别,只是在本例中,您将类对象本身用作委托,而不是某个实例,从而省去了创建另一个对象的需要。