最终编辑
解决所有生活中的问题:
将xcode的“编译器版本”设置切换为“LLVM编译器2.0”解决了这个问题,非常感谢Firoze Lafeer提供的协调一致的建设性帮助!
意图是在我的所有类中构建一些非常基本的功能,通过继承NSObject和UIViewController来获取应用程序委托,稍微扩展viewDidAppear机制等等。我有一个看起来像这样的基类(只包括相关的行):
@interface PHView : UIViewController {
id<PHAppDelegate> appDelegate;
}
-(id)init;
//some other method prototypes
@property (nonatomic, retain) id delegate;
@end
@implementation PHView
@synthesize delegate;
-(id)init {
self = [super init];
appDelegate = (id<PHAppDelegate>)[[UIApplication sharedApplication] delegate];
visible = FALSE;
initialized = FALSE;
return self;
}
//some other methods
@end
编辑我应该在这里提一下,属性“委托”并不意味着指向ivar“appDelegate”或任何东西......我只是留下它来说明这个超类使用@synthesize 。由于它不是一个相关的用途我认为并不重要,但我不会说我知道。
子类的接口:
@interface PinMap : PHView <MKMapViewDelegate> {
//@interface PinMap : UIViewController <MKMapViewDelegate> {
// NSObject<PHAppDelegate>* appDelegate;
}
-(id)init;
-(void)zoomToUser;
@property (nonatomic, retain) IBOutlet MKMapView* map;
@end
编译:
@implementation PinMap
//@synthesize map;
-(PinMap*) init{
self = [super init];
//appDelegate = (NSObject<PHAppDelegate>*)[[UIApplication sharedApplication] delegate];
return self;
}
-(void)zoomToUser {
//MKCoordinateRegion region = map.region;
MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake((CLLocationDegrees)300, (CLLocationDegrees)300), MKCoordinateSpanMake((CLLocationDegrees)20,(CLLocationDegrees)20)); //random region
region.center = [[appDelegate location] coordinate];
region.span.longitudeDelta /= 50.0;
region.span.latitudeDelta /= 50.0;
// [map setRegion:region animated:NO];
}
这不编译:
@implementation PinMap
@synthesize map;
-(PinMap*) init{
self = [super init];
//appDelegate = (NSObject<PHAppDelegate>*)[[UIApplication sharedApplication] delegate];
return self;
}
-(void)zoomToUser {
MKCoordinateRegion region = map.region;
//MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake((CLLocationDegrees)300, (CLLocationDegrees)300), MKCoordinateSpanMake((CLLocationDegrees)20,(CLLocationDegrees)20)); //random region
region.center = [[appDelegate location] coordinate]; // <-- ERROR HERE
region.span.longitudeDelta /= 50.0;
region.span.latitudeDelta /= 50.0;
[map setRegion:region animated:NO];
}
在标记的位置,我得到“”“appDelegate”未声明(首次使用此功能)“”“我的第一步是清理,重新启动并再次清理(本周使用该程序修复了三个错误)以及何时那些不起作用的我开始尝试有意义的事情,最后是一些没有意义的事情。
以下DOES编译(并运行)但我老实说不明白为什么:
@interface PinMap : PHView <MKMapViewDelegate> {
//@interface PinMap : UIViewController <MKMapViewDelegate> {
//NSObject<PHAppDelegate>* appDelegate;
MKMapView* _map;
}
-(id)init;
-(void)zoomToUser;
@property (nonatomic, retain) IBOutlet MKMapView* map;
@end
@implementation PinMap
@synthesize map=_map;
-(PinMap*) init{
self = [super init];
//appDelegate = (NSObject<PHAppDelegate>*)[[UIApplication sharedApplication] delegate];
return self;
}
-(void)zoomToUser {
MKCoordinateRegion region = self.map.region;
//MKCoordinateRegion region = MKCoordinateRegionMake(CLLocationCoordinate2DMake((CLLocationDegrees)300, (CLLocationDegrees)300), MKCoordinateSpanMake((CLLocationDegrees)20,(CLLocationDegrees)20)); //random region
region.center = [[appDelegate location] coordinate];
region.span.longitudeDelta /= 50.0;
region.span.latitudeDelta /= 50.0;
[self.map setRegion:region animated:NO];
}
在此修剪中,它将响应“self.map”,但认为“map”未声明。
编辑“自我”要求现在对我有意义,但消失/重新出现的“appDelegate”ivar是我真正担心的。对不起,如果以前不清楚。但严重的是,那是怎么回事?
答案 0 :(得分:2)
嗯,对于初学者来说,PinMap没有名为'map'的实例变量(ivar)。
它有一个名为'map'的属性,您可以这样访问:
region = self.map.region;
或者它有一个名为_map的ivar。所以你可以这样做:
region = _map.region;
但前者是推荐的。你创建了一个属性,所以你可能想要使用它(在initXXX和dealloc之外)
修改强>
此外,UIViewController的指定初始化程序是initWithNibName:bundle:
因此,请确保您是否将UIViewController子类化为您指定的初始化程序。
再次编辑
在评论中的那些情况下,您可能有一个ivar和一个同名的属性。如果你只是做@synthesize propname,那就是你得到的。但是在这种情况下你做了@synthesize map = _map。
值得花时间了解您何时直接访问ivar,而不是财产。否则很多事情都没有意义,其他错误也会发生。要访问该属性,您必须执行'self.propertyName'(或[self propertyName]或[self setPropertyName:something])
如果你没有使用self,你就不会使用getter / setter(这通常是一件坏事,例如你的getter / setter正在为你做内存管理或初始化)。如果您不打算使用该属性,您还必须使用实际的ivar名称。
再次编辑
我看到改变编译器有帮助。我会建议两件事:仔细检查你所有的@synthesize语句,以确保你没有要求编译器在已经存在于超类中的子类中合成一个ivar。当你对它进行排序时,我会建议你将你的ivars命名为variable_或_variable,这样你就可以很容易地看到你使用ivar和财产的位置。
更重要的是,您应该真正升级到XVM 4.2.1中包含的LLVM 3.0。
答案 1 :(得分:0)
@synthesize
为属性创建setter和getter方法,但是它需要一些地方来存储该对象,因此您必须添加某种ivar以将@synthesize与属性一起使用
你可以做到
@interface ... : ... {
Something* smth;
}
@property (nonatomic, retain) Something *smth;
@end
@implementation ...
@synthesize smth;
@end
或
@interface ... : ... {
Something* _smth;
}
@property (nonatomic, retain) Something *smth;
@end
@implementation ...
@synthesize smth=_smth;
@end