最终编辑
  
  解决生活中所有问题的方法:
  
  
  将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


编辑我在这里应该提到,属性“ delegate”并不意味着指向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”(此功能首次使用)“”“我的第一步是清理,重新启动并再次清理(本周使用该过程修复了三个错误),而在不这样做的时候,工作开始,我开始尝试有意义的事情,最后尝试一些没有意义的事情。

以下确实可以编译(并运行),但老实说我不明白为什么:

@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是我真正担心的。抱歉,如果以前不清楚。但是说真的,这是怎么回事?

最佳答案

好吧,对于初学者而言,PinMap没有名为“ map”的实例变量(ivar)。

它具有一个称为“地图”的属性,您可以像这样访问:

region = self.map.region;


或者它有一个名为_map的ivar。因此,您可以这样做:

region = _map.region;


但是建议使用前者。您做了一个属性,因此您可能要使用它(在initXXX和dealloc之外)

编辑

同样,UIViewController的指定初始化器是initWithNibName:bundle:

因此,只要确定是否将UIViewController子类化,就可以调用其指定的初始化程序。

再次编辑

在这些情况下,您的注释中可能有一个ivar和一个具有相同名称的属性。如果您只使用@synthesize属性名,那就可以了。但是在这种情况下,您执行了@synthesize map = _map。

值得花些时间来了解何时直接访问ivar和属性。否则,很多事情将毫无意义,并且还会发生其他错误。要访问该属性,您必须执行“ self.propertyName”(或[self propertyName]或[self setPropertyName:something])

如果您不使用self,那么您就不会使用getter / setter(这通常是一件坏事,例如,如果您的getter / setter正在为您执行内存管理或初始化)。如果您不打算使用该属性,则还必须使用实际的ivar名称。

再次编辑

我看到更改编译器有所帮助。然后,我建议两件事:仔细检查所有@synthesize语句,以确保您不要求编译器在超类中已经存在的子类中合成ivar。当您进行排序时,我建议您将ivars命名为variable_或_variable,以便您可以轻松地看到ivar和property在哪里使用。

更重要的是,您应该真正升级到Xcode 4.2.1中包含的LLVM 3.0。

关于iphone - @synthesize干扰继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8349609/

10-12 14:47