【问题标题】:Are @property's necessary for Interface Builder?Interface Builder 是否需要@property?
【发布时间】:2011-06-02 13:21:13
【问题描述】:

在我的 UIViewController 子类中,我有 3 个 UIView,每个 @property 作为 IBOutlet。我的代码中根本不使用这些属性。视图在创建视图控制器后立即被实例化,并在视图控制器被释放时被释放。

我在想;我不能只删除@property's 吗?我做到了,我仍然可以在 Interface Builder 中连接我的实例变量(使用 IBOutlet)。

所以我现在的问题是; 属性与 Interface Builder 结合使用有什么用,还是可以将它们排除在外? 是否需要一些内存管理或其他什么?还是它们真的只是为了在您自己的代码中使用?

如果我确实将它们排除在外,我还需要在deallocrelease 他们吗?

【问题讨论】:

    标签: iphone objective-c cocoa-touch uikit interface-builder


    【解决方案1】:

    它们不是必需的,但由于它们阐明了内存管理这一简单事实,我们强烈鼓励它们。

    例如,如果您通过 ivar 声明一个 outlet,那么它的保留策略是什么?是否保留?它是自动发布的吗?你是业主吗?其他人也拥有它吗?那里有很多模棱两可的地方(尤其是那些该死的顶级对象,它们在 Mac 上的行为与在 iPhone 上的行为不同)。

    另一方面,如果你通过一个属性来声明outlet,就没有歧义了,因为内存管理策略是直接在声明中声明的。除了属性的存在之外,nib 取消归档将看到 setter 并使用它,从而确保转移对象所有权等不会发生任何奇怪的事情。

    简而言之,您可以在不使用@property 的情况下声明出口(在 10.5 中引入它们之前我们都必须这样做),但没有充分的理由使用它们。它们确实使代码更清楚地了解到底发生了什么。

    有关 nib 对象内存管理荒谬的更多信息,check out this page in the documentation

    【讨论】:

    • 出于兴趣,如果不定义@property,它应该使用默认值,所以变量都会被赋值而不是保留、读写和原子;)
    • @iPortable 不一定。顶级对象有一些额外的时髦警告。有时你仍然需要释放它们,有时你不需要。就像我说的,这非常愚蠢,使用属性只会让每个人的工作变得更轻松。
    • 我讨厌有人可以从另一个类访问我的变量的想法。有没有办法特别否认这一点?
    • 我决定尽可能删除它们。对我来说代码更少。我知道每个 @property 只有 2 行代码,但如果我有 3 个 @property,那就是 6 行代码。
    • 这篇文章很老了。现在一天 ARC 正在处理内存。除了这个调用 getter 和 setter 更昂贵。
    【解决方案2】:

    为视图使用属性有两个原因:

    • 更简单/更安全的内存管理(非常好的理由)
    • 将您的界面暴露给其他类(通常是不好的编码习惯)

    我总是使用属性来确保如果我忘记在 viewDidUnload 中清零 IBOutlets,我的代码不会崩溃。毕竟只写两行代码并不难。

    如果您想节省一些输入,则根本不要声明 ivars。下面的代码可以正常工作:

    @interface MyController : UIController {
    }
    @property (nonatomic, retain) IBOutlet UIImageView* myImage;
    @end
    
    @implementation MyController
    @synthesize myImage;
    
    - (void) dealloc() 
    { 
       self.myImage = nil;
       [super dealloc];
    }    
    
    - (void) viewDidUnload()
    { 
       self.myImage = nil;
       [super viewDidUnload];
    }
    @end
    

    【讨论】:

    • 在所有苹果的示例代码中,IB var 在 vi​​ewDidUnload 中为零并在 dealloc 中释放
    • @iPortable 确实如此,但是在 dealloc 中将其设为 nil 并没有什么坏处,如果您将 @property 从“保留”更改为“分配”,它也不会崩溃。
    • @iPortable 我已经发布了一个关于取消属性的​​问题:stackoverflow.com/questions/4579891/…
    【解决方案3】:

    Interface Builder 或 NIB 加载器不依赖于存在的属性。如果可以通过 KVC 访问连接的变量,则 nib 加载器可以建立连接。

    但是您确实应该考虑使用合成属性而不是手写访问器。这不太容易出错,因为它不需要那么多样板代码。编写的代码越少越好。

    【讨论】:

    • 也许只有我看不到依赖关系,所以只想确保:不需要合成值,因为如果没有定义 @property,它将使用默认的 getter 和 setter。跨度>
    • 是的。即使你有@synthesize 行,你的手写setter 和getter 也会被使用。标题中的@property NSString *foo 只是写-(NSString *)foo; -(void)setFoo:(NSString *)newFoo; 并记录@synthesize 使用的一些信息的另一种方式。
    【解决方案4】:

    如果您不打算从其他视图控制器或对象操作或访问有关您的视图的信息,并计划在内部使用它们(在拥有视图控制器中),则根本不需要 @property 声明。只需在视图控制器的界面中将它们定义为 IBOutlet 实例变量即可。

    【讨论】:

      【解决方案5】:

      是的,你可以:

      @interface SomeClass : UIViewController {
          IBOutlet UILabel *myLabel;
      }
      
      @end
      

      @property 仅用于定义内存管理和 getter 和 setter、读写能力等。

      【讨论】:

      • 如果我把它们排除在外,我还需要在 dealloc 中释放它们吗?
      • 我不太清楚(可能需要再次阅读文档),但我释放了我在头文件中声明的所有对象。 (也许是错的,但我完全没有错误^^)
      • @Rits 您不必在 dealloc 中释放它们,因为它们在分配给 ivars 时不会保留。仅当您使用属性(保留)时,您才需要在 dealloc 中释放
      • @Rits 您的评论正是建议通过属性声明网点的确切原因。
      • @Piotr 这并不总是正确的。
      猜你喜欢
      • 2010-12-19
      • 2012-03-09
      • 2021-08-07
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多