2017-02-20 108 views
0

我試圖自定義對象傳遞給下一個視圖控制器,我遇到這個錯誤爲什麼類對象的屬性保留而不是複製?

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 

    if ([segue.identifier isEqualToString:@"attemptDetails"]) 
    { 
     ResultsVC *vc = segue.destinationViewController; 
     vc.selectedEntry = selectedEntry; 
    } 
} 

@property (nonatomic, retain) ClassName *selectedEntry; //Why is it retain and not copy?

我仍然很困惑財產屬性和爲什麼某些類型使用某些屬性,像NSString使用(nonatomic, copy)和CLLocationCoordinate2D使用(nonatomic, readonly)

有人可以解釋或鏈接引用我如何每個屬性的作品?非常感謝!

+2

檢查此答案:http:// stackoverflow。com/a/7855536/4831524 –

+1

檢查此鏈接,http://stackoverflow.com/questions/2255861/property-and-retain-assign-copy-nonatomic-in-objective-c http://stackoverflow.com/a/15541801/4294543 –

+0

@iamhx你給故事板中的標識符? –

回答

0

在Objective C中,你會發現每個類實際上都有一個結構。這些屬性是創建結構中的值的快捷方式,一個getter和一個setter。例如:

@interface MyClass 

@property id myValue; 

@end 

將創建:

@interface MyClass { 
    id _myValue; 
} 

@property id myValue; 

@end 

@implementation 

- (id)myValue { 
    return _myValue; 
} 
- (void)setMyValue:(id)myValue { 
    _myValue = myValue; 
} 

@end 

現在,這些標誌,如retaincopy添加額外的邏輯來的getter和setter方法。使用copy實際上將創建一個setter爲:

- (void)setMyValue:(id)myValue { 
    _myValue = [myValue copy]; 
} 

這意味着該值必須有copy方法來實現。由於你的對象不會崩潰。

爲什麼使用副本是爲了安全。這對於字符串而言很少重要,但對於像數組這樣的東西很重要。因此,例如,您創建一個屬性@property NSArray *myArray;,該屬性需要一個不可變數組,但問題是您可以設置一個可變數組:myClassInstance.myArray = [[NSMutableArray alloc] init];。現在2個模塊可以訪問相同的可變數組。因此,如果第一個對象開始修改數組,而另一個期望該數組始終保持不變,則可能會發現一些問題。例如MyClass實例可能會將其用作表視圖的數據源,並且在某些時候數組會發生變化,但不會添加/刪除單元格,並且表視圖會導致崩潰。

說實話,你可以簡單地把所有這些作爲默認值,只有當你真的需要時才能修改它們。無論如何,上述情況極不可能。

+0

有意思......我想問一下,在.h文件的'@interface {}'中你可以聲明它的東西(例如'NSString * myString;'),並將它用在你的.m文件中, self.myString;'。我的問題是,在.m文件中還有一個'@interface {}'。這兩個接口都是同一個東西嗎? – iamhx

+1

它們是相同的,但源文件(.m)中的文件通常被視爲私有文件(或文件私有文件)。在大多數情況下,我們嘗試聲明所有內容,但需要暴露給其他類,文件的值。而那些暴露的應該總是屬性,所以你可以控制邏輯,而不需要改變該類之外的邏輯(比如重寫setter)。總之,將所有這些都放在源文件中,除非你100%確定你在做什麼,如優化性能。 –

+0

另請注意,如果接口具有隻讀標誌,則可以在接口和源文件中都具有相同的屬性。這意味着您將以只讀方式公開該屬性,但可以在源文件內部將其分配給它。 –

1

有很多描述的財產屬性的解釋,

參考鏈接,

Objective-C ARC: strong vs retain and weak vs assign

https://stackoverflow.com/a/4511004/4294543

@property and retain, assign, copy, nonatomic in Objective-C

短&簡單我的理解是一樣,

保留:它正在處理創建的對象,它只是增加引用計數。

  • 在這裏,你的情況,你已經模型類對象,因此不需要在第二VC屬性複製,你只需要把它保留第二VC財產。

副本:你分配給屬性的值可以被複制使用&用於其他用途太(當對象是可變的&需要完成後釋放它創建對象的淺拷貝&需要)。

非原子:線程訪問速度更快,但不能同時訪問&更改屬性。

只讀:您不能直接分配屬性新值。

即使我已經在我的項目運行情況,

#import "ViewController.h" 
#import "TestViewController.h" 
#import "CustomClass.h" 
@interface ViewController(){ 

    CustomClass *classT; 
} 

@end 
@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    classT = [[CustomClass alloc]init]; 
    classT.test = YES; 

} 
- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 
- (IBAction)btn:(id)sender { 
    TestViewController * vc = [self.storyboard instantiateViewControllerWithIdentifier:@"TestViewController"]; 
    vc.className = classT; 
    [self presentViewController:vc animated:YES completion:nil]; 
} 
@end 




#import <UIKit/UIKit.h> 
#import "CustomClass.h" 

@interface TestViewController : UIViewController 


@property (nonatomic,retain) CustomClass *className; // Work as i said 

//@property (nonatomic,copy) CustomClass *className; // Makes a copy of an object, and returns it with retain count of 1. If you copy an object, you own the copy. This applies to any method that contains the word copy where 「copy」 refers to the object being returned thats why here you will get crash 


@end 
1

我看了幾個好文章的內存管理。據rypress

保留屬性:該保留屬性是手動保留的強勢發佈版本,它具有完全相同的效果:自稱賦值的所有權。您不應該在自動參考計數環境中使用它。

複製屬性:copy屬性是strong的替代方法。它不是取得現有對象的所有權,而是創建您分配給該屬性的任何副本,然後獲取該屬性的所有權。只有符合NSCopying協議的對象才能使用此屬性。

即使我也經歷了一些很好的stackoverflow鏈接。 Joshua Nozzi's answer對保留與複製給出了很好的解釋。

保留對複製 - 聲明的屬性默認情況下使用保留(這樣你就可以簡單地完全忽略它的),並會自動管理對象的引用計數另一個對象是否被分配給屬性或將它設置爲無;使用副本自動發送新分配的對象一個-copy消息(它將創建一個傳遞的對象的副本,並將該副本分配給該屬性 - 有用的(甚至是必需的)在某些情況下,分配的對象可能會被修改後設置爲某些其他對象的性質(這將意味着修飾/突變將適用於屬性爲好)

還找到很好的例子here

代碼:。

NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:@"First",@"Second", nil]; 
    NSMutableArray *copiedArray = [array mutableCopy]; 
    NSMutableArray *retainedArray = [array retain]; 

    [retainedArray addObject:@"Retained Third"]; 
    [copiedArray addObject:@"Copied Third"]; 

    NSLog(@"array = %@",array); 
    NSLog(@"Retained Array = %@",retainedArray); 
    NSLog(@"Copied Array = %@",copiedArray); 

輸出:

array = (
    First, 
    Second, 
    "Retained Third" 
) 
2013-12-19 17:15:49.380 RetainVsCopy[2876:c07] Retained Array = (
    First, 
    Second, 
    "Retained Third" 
) 
2013-12-19 17:15:49.381 RetainVsCopy[2876:c07] Copied Array = (
    First, 
    Second, 
    "Copied Third" 
) 

請參見數組和保留數組都有相同的內容。這是因爲兩者都指向相同的內存/實例/對象。複製陣列的內容不同。這是因爲複製創建了一個單獨的實例。

相關問題