Objective C方法和属性可以具有相同的名称吗?

时间:2016-02-07 14:12:40

标签: ios objective-c properties

我正在查看关于目标C和IOS的核心数据的教程,这是我遇到的:

在头文件中:

@interface CoursesTableViewController : UITableViewController <AddCourseViewControllerDelegate,NSFetchedResultsControllerDelegate>

@property (nonatomic,strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic,strong) NSFetchedResultsController *fetchedResultsController;


@end

并且实现中的方法具有:

-(NSFetchedResultsController *)fetchedResultsController{
    if(_fetchedResultsController!=nil){
        return _fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Course" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];
    // Specify criteria for filtering which objects to fetch

    // Specify how the fetched objects should be sorted
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"author" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObjects:sortDescriptor, nil]];
    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"author" cacheName:nil];


    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

}

属性fetchedResultsController和实例方法fetchedResultsController都具有完全相同的名称。

  1. 如何区分这两种方法?
  2. 这有特殊意义吗? (比如方法的名称与类相同意味着它是一个构造函数)

1 个答案:

答案 0 :(得分:6)

@property的声明实际上是为你创造了三件事;

  1. 用于存储属性的支持变量
  2. 一个setter方法和
  3. 一种吸气方法。 (除非该属性是只读的,在这种情况下没有setter方法)。
  4. @property SomeType *someProperty;

    将创建一个支持变量(默认情况下称为_someProperty),这是一个看起来像的setter方法:

    -(void) setSomeProperty:(SomeType *)value {
       _someProperty=value;
    }
    

    一个看起来像

    的getter方法
    -(SomeType *)someProperty {
        return _someProperty;
    }
    

    您可以看到访问“属性”实际上只是方法调用。

    编译器知道myObject.someProperty=someNewValue;实际上是[myObject setSomeProperty:someNewValue]myObject.someProperty实际上是[myObject someProperty]。实际上,如果单步执行引用调试器中的属性的行,您将看到执行跳转到属性定义;这是getter或setter方法的调用。

    在您显示的代码中,已明确指定了getter方法,因此编译器将不提供它通常会提供的默认实现。在这种情况下,这是属性可以懒惰地实例化;您会看到代码检查后备变量_fetchedResultsController是否为零。如果不是,它只是返回值。如果是,则设置一个新的,将其保存到支持变量并返回它。

    当您使用_propertyName时,您绕过了setter / getter。我看到许多程序员这样做是因为他们认为这只是属性的“简写”,但正如你从示例中看到的那样,绕过getter会导致问题。只有在有原因时才应绕过属性设置器和getter。

    你应绕过setter的地方是setter本身。如果你有

    -(void) setSomeProperty:(SomeType *)value {
       self.someProperty=value;
    }
    

    然后你会得到一个无限循环,因为这段代码真的是

    -(void) setSomeProperty:(SomeType *)value {
       [self setSomeProperty:value];
    }
    

    有趣的是,'getter'语法适用于任何不带参数的非void方法,因此即使[NSUserDefaults standardUserDefaults]不是属性,NSUserDefaults.standardUserDefaults也可以写standardUserDefaults。 / p>