【问题标题】:incompatible Objective-c types warning不兼容的 Objective-c 类型警告
【发布时间】:2011-04-14 05:59:21
【问题描述】:

我有一个通过 iPhone 应用程序使用的用户类,这是我的用户类(NSobject 的子类)中的 init 和 initWithUser 函数,当我使用 initWithUser 函数时,我收到代码后描述的警告。请指教。

// serialize.h 
#import <Foundation/Foundation.h>

@protocol Serialize

// serialize the object to an xml string
-(NSString*)ToXML;

@end


// user.h
#import <Foundation/Foundation.h>
#import "Serialize.h"
#import "Contact.h"


@interface User : NSObject <Serialize> {

NSString *email;
NSString *firstName;
NSString *lastName;
NSString *userId;
NSString *userName;
NSString *password;

NSMutableArray *contactList;

}

@property (nonatomic,copy) NSString *email;
@property (nonatomic,copy) NSString *firstName;
@property (nonatomic,copy) NSString *lastName;
@property (nonatomic,copy) NSString *userId;
@property (nonatomic,copy) NSString *userName;
@property (nonatomic,copy) NSString *password;
@property (nonatomic, retain) NSMutableArray *contactList;

//-(id)init;
-(id)initWithUser:(User *)copyUser;

@end



// user.m 
#import "user.h"


@implementation User

@synthesize email;
@synthesize firstName;
@synthesize lastName;
@synthesize userId;
@synthesize userName;
@synthesize password;
@synthesize contactList;

-(id)init
{
    // call init in parent and assign to self
    if( (self = [super init]) ) 
    {          
        // do something specific 
        contactList = [[NSMutableArray alloc] init];

    }
    return self;
}

-(id)initWithUser:(User *)copyUser
{
    if( (self = [self init]) ) {           

        email               = copyUser.email;
        firstName           = copyUser.firstName;
        lastName            = copyUser.lastName;
        userId              = copyUser.userId;
        userName            = copyUser.userName;
        password            = copyUser.password;

        // release contactList initialized in the init
        [contactList release];
        contactList         = [copyUser.contactList mutableCopy];
    }

    return self;
}

- (void)dealloc
{
    // TODO: 
    [contactList removeAllObjects];
    [contactList release];
    [super dealloc];
}

// implementation of serialize protocol
-(NSString*)ToXML
{
    return @""; 
}

我在主控制器中这样使用它

- (void) registerNewUser {

    RegistrationViewController *regController = [[RegistrationViewController alloc] init] ;

    regController.newUser = [[User alloc] initWithUser:self.user];

    [self.navigationController pushViewController:regController animated:YES];
    [regController release];

}

一行

regController.newUser = [[User alloc] initWithUser:self.user];

给我以下错误,这几天让我发疯:

不兼容的 Objective-c 类型 'struct User*',当从不同的 Objective-c 类型传递 'initWithUser:' 的参数 1 时需要 'struct NSString *'

感谢任何帮助和指导

【问题讨论】:

  • 嗯。你能发布User.h 文件吗?
  • Serialize 看起来像什么?你有什么奇怪的NSObject 类别吗?任何可能涉及的#define
  • 我在上面添加了序列化代码,没有#define或类似的东西
  • 确实很奇怪,我得到了同样的错误,但只是将initWithUser: 方法重命名为initWithAUser: 会使警告消失。尽管即使使用原始名称,它也会在运行时调用正确的方法。
  • 一些后续说明:在这里重用-init 是多余的。像email 这样的ivar 赋值应该是copyretain[contactList removeAllObjects] 是多余的。最后,如前所述,newUser 被过度保留,必须在调用属性设置器后释放实例。

标签: objective-c ios4


【解决方案1】:

如 cmets 中所述,您的实施还存在其他问题。在您的初始化程序中,重用 -init 是多余的,并且分配给像 email 这样的 ivars 应该使用 -copy-retain 获得数据的所有权:

-(id)initWithUser:(User *)copyUser {
    if((self = [super init])) {
        // take ownership of the users data by copying or retaining:
        email = [copyUser.email copy];
        // ...

        contactList = [copyUser.contactList mutableCopy];
    }    
    return self;
}

-dealloc中,-removeAllObjects可以被移除,会员数据要发布:

- (void)dealloc {
    [email release];
    // ...

    [contactList release];
    [super dealloc];
}

请注意,如果newUsercopyretain 属性,您也会泄漏新的User 实例,因为缺少release

User *user = [[User alloc] initWithUser:self.user];
regController.newUser = user;
[user release];

【讨论】:

    【解决方案2】:

    问题是你有一个模棱两可的选择器。因为alloc 返回id,所以对initWithUser: 的调用变得模棱两可。 NSUserDefaults 也有一个 initWithUser: 函数,它接受一个字符串。编译器认为您正在尝试使用那个。将行改为

    regController.newUser = [(User*)[User alloc] initWithUser:self.user];
    

    一切都应该按预期工作。

    【讨论】:

    • 非常感谢,我将名称更改为 initWithAUser 以消除歧义。我不会想到这一点,你为我省去了很多挫折。并感谢大家的帮助。
    • 好电话。在我看来,编译器警告应该能够说明它是模棱两可的,而不是参数的类型错误,因为没有特别的理由更喜欢 NSUserDefault 而不是 User。
    • 我认为 Clang 可能对这种情况有更好的警告。在一个完美的世界中,它将能够查看您分配的类型并选择返回该类型的正确选择器。
    猜你喜欢
    • 1970-01-01
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2015-10-10
    相关资源
    最近更新 更多