Решение:
# /initializers/string.rb
class String
IntegerRegex = /^(\d)+$/
def integer?
!!self.match(IntegerRegex)
end
end
# any_model_or_controller.rb
'12345'.integer? # true
'asd34'.integer? # false
Объяснение:
/^(\d)+$/
- выражение regex для нахождения цифр в любой строке. Вы можете проверить выражения и результаты регулярных выражений на http://rubular.com/ . IntegerRegex
, чтобы избежать ненужного выделения памяти каждый раз, когда мы ее используем в методе. integer?
- это вопросительный метод, который должен возвращать true
или false
. match
- метод в строке, который соответствует вхождениям в соответствии с данное выражение регулярного выражения в аргументе и возвращает согласованные значения или nil
. !!
преобразует результат метода match
в эквивалентный булев. String
- это исправление обезьяны, которое ничего не меняет в существующих функциях String, но добавляет еще один метод с именем integer?
для любого объекта String. Нет никаких "удобных методов", если Вы не кодируете их сами, но необходимо было бы все еще реализовать методы делегата в любом пользовательском коде, который Вы используете для создания вещей "удобными".
шаблон делегата там по причине, и поскольку делегаты являются большой частью Objective C, я рекомендую стать довольными ими.
Нет такого удобства, и Вы не должны создавать свое собственное. "Блоки, пока это не получает результат", чрезвычайно плохи практика программирования на устройстве как iPhone. Могут потребоваться секунды для получения местоположения; Вы никогда не должны заставлять своих пользователей ожидать как этот, и делегаты удостоверяются, чтобы они не делали.
То, что я делаю, реализовать singleton-класс для управления обновлениями от базового местоположения. Для доступа к моему текущему местоположению я делаю CLLocation *myLocation = [[LocationManager sharedInstance] currentLocation];
, Если бы Вы хотели заблокировать основной поток, то Вы могли бы сделать что-то вроде этого:
while ([[LocationManager sharedInstance] locationKnown] == NO){
//blocking here
//do stuff here, dont forget to have some kind of timeout to get out of this blocked //state
}
Однако, как на это уже указали, блокируя основной поток, вероятно, не хорошая идея, но это может быть хорошей стартовой точкой, поскольку Вы создаете что-то. Вы также заметите, что класс я выписал чеки метка времени на обновлениях информации о местоположении и игнорирую любого, которые стары, для препятствования проблеме получения устаревших данных базовое местоположение.
Это - singleton-класс, который я записал. Обратите внимание на то, что это немного грубо вокруг краев:
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
@interface LocationController : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
+ (LocationController *)sharedInstance;
-(void) start;
-(void) stop;
-(BOOL) locationKnown;
@property (nonatomic, retain) CLLocation *currentLocation;
@end
@implementation LocationController
@synthesize currentLocation;
static LocationController *sharedInstance;
+ (LocationController *)sharedInstance {
@synchronized(self) {
if (!sharedInstance)
sharedInstance=[[LocationController alloc] init];
}
return sharedInstance;
}
+(id)alloc {
@synchronized(self) {
NSAssert(sharedInstance == nil, @"Attempted to allocate a second instance of a singleton LocationController.");
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id) init {
if (self = [super init]) {
self.currentLocation = [[CLLocation alloc] init];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[self start];
}
return self;
}
-(void) start {
[locationManager startUpdatingLocation];
}
-(void) stop {
[locationManager stopUpdatingLocation];
}
-(BOOL) locationKnown {
if (round(currentLocation.speed) == -1) return NO; else return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//if the time interval returned from core location is more than two minutes we ignore it because it might be from an old session
if ( abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 120) {
self.currentLocation = newLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *alert;
alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[error description] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
-(void) dealloc {
[locationManager release];
[currentLocation release];
[super dealloc];
}
@end