2009-07-20 8 views

答えて

2

これは私が長年前に見つけたものに基づいて思いついたものです。これはPythonで書き直され、複数のプロパティを同時に生成できるという改良が加えられました。

(コピー)を属性として使用して、選択したすべてのインスタンス変数のプロパティを生成します。

ファイル内に複数の@interfacesや@implementationがあるエッジケースや、異常な識別子やアスタリスクの配置(* constなど)があるものもありますが、最も一般的なコーディングスタイルをカバーする必要があります。これらのケースのいずれかを修正した場合は、編集/投稿を自由に行ってください。

#!/usr/bin/python 

# Takes a header file with one or more instance variables selected 
# and creates properties and synthesize directives for the selected properties. 

# Accepts google-style instance variables with a tailing underscore and 
# creates an appropriately named property without underscore. 

# Entire Document 
# Home Directory 
# Discard Output 
# Display in Alert 

import os 
import re 
import subprocess 

# AppleScripts for altering contents of files via Xcode 
setFileContentsScript = """\ 
on run argv 
    set fileAlias to POSIX file (item 1 of argv) 
    set newDocText to (item 2 of argv) 
    tell application "Xcode" 
     set doc to open fileAlias 
     set text of doc to newDocText 
    end tell 
end run \ 
""" 

getFileContentsScript = """\ 
on run argv 
    set fileAlias to POSIX file (item 1 of argv) 
    tell application "Xcode" 
     set doc to open fileAlias 
     set docText to text of doc 
    end tell 
    return docText 
end run \ 
""" 

# Get variables from Xcode 
headerFileText = """%%%{PBXAllText}%%%""" 
selectionStartIndex = %%%{PBXSelectionStart}%%% 
selectionEndIndex = %%%{PBXSelectionEnd}%%% 
selectedText = headerFileText[selectionStartIndex:selectionEndIndex] 

headerFilePath = """%%%{PBXFilePath}%%%""" 

# Look for an implementation file with .m or .mm extension 
implementationFilePath = headerFilePath[:-1] + "m" 
if not os.path.exists(implementationFilePath): 
    implementationFilePath += "m" 

instanceVariablesRegex = re.compile(
    """^\s*((?:(?:\w+)\s+)*(?:(?:\w+)))""" + # Identifier(s) 
    """([*]?)\\s*""" + # An optional asterisk 
    """(\\w+?)(_?);""", # The variable name 
    re.M) 

# Now for each instance variable in the selected section 
properties = "" 
synthesizes = "" 

for lineMatch in instanceVariablesRegex.findall(selectedText): 
    types = " ".join(lineMatch[0].split()) # Clean up consequtive whitespace 
    asterisk = lineMatch[1] 
    variableName = lineMatch[2] 
    trailingUnderscore = lineMatch[3] 

    pointerPropertyAttributes = "(copy) " # Attributes if variable is pointer 
    if not asterisk: 
     pointerPropertyAttributes = "" 

    newProperty = "@property %s%s %s%s;\n" % (pointerPropertyAttributes, 
              types, 
              asterisk, 
              variableName) 

    # If there's a trailing underscore, we need to let the synthesize 
    # know which backing variable it's using 
    newSynthesize = "@synthesize %s%s;\n" % (variableName, 
              trailingUnderscore and 
              " = %s_" % variableName) 

    properties += newProperty 
    synthesizes += newSynthesize 

# Check to make sure at least 1 properties was found to generate 
if not properties: 
    os.sys.stderr.writelines("No properties found to generate") 
    exit(-1) 

# We want to insert the new properties either immediately after the last 
# existing property or at the end of the instance variable section 
findLastPropertyRegex = re.compile("^@interface.*?{.*?}.*?\\n" + 
            "(?:.*^\\s*@property.*?\\n)?", re.M | re.S) 
headerInsertIndex = findLastPropertyRegex.search(headerFileText).end() 

# Add new lines on either side if this is the only property in the file 
addedNewLine = "\n" 
if re.search("^\s*@property", headerFileText, re.M): 
    # Not the only property, don't add 
    addedNewLine = "" 

newHeaderFileText = "%s%s%s%s" % (headerFileText[:headerInsertIndex], 
           addedNewLine, 
           properties, 
           headerFileText[headerInsertIndex:]) 

subprocess.call(["osascript", 
       "-e", 
       setFileContentsScript, 
       headerFilePath, 
       newHeaderFileText]) 


if not os.path.exists(implementationFilePath): 
    os.sys.stdout.writelines("No implementation file found") 
    exit(0) 

implementationFileText = subprocess.Popen(
    ["osascript", 
    "-e", 
    getFileContentsScript, 
    implementationFilePath], 
    stdout=subprocess.PIPE).communicate()[0] 

# We want to insert the synthesizes either immediately after the last existing 
# @synthesize or after the @implementation directive 
lastSynthesizeRegex = re.compile("^\\s*@implementation.*?\\n" + 
           "(?:.*^\\s*@synthesize.*?\\n)?", re.M | re.S) 

implementationInsertIndex = \ 
    lastSynthesizeRegex.search(implementationFileText).end() 

# Add new lines on either side if this is the only synthesize in the file 
addedNewLine = "\n" 
if re.search("^\s*@synthesize", implementationFileText, re.M): 
    # Not the only synthesize, don't add 
    addedNewLine = "" 

newImplementationFileText = "%s%s%s%s" % \ 
        (implementationFileText[:implementationInsertIndex], 
        addedNewLine, 
        synthesizes, 
        implementationFileText[implementationInsertIndex:]) 

subprocess.call(["osascript", 
       "-e", 
       setFileContentsScript, 
       implementationFilePath, 
       newImplementationFileText]) 

# Switch Xcode back to header file 
subprocess.Popen(["osascript", 
        "-e", 
        getFileContentsScript, 
        headerFilePath], 
       stdout=subprocess.PIPE).communicate() 
+0

ええとを入力するように物事読みやすく、かつ迅速になりそうではありません2つのeで "合成する"?私はこのスクリプトが「synthsize」という綴りで正しく動作しないと想定しています。 – n8gray

+0

はい、それを指摘してくれてありがとう。 –

0

ここで私は数時間後にこの質問を越えてくる前に@propertyディレクティブを行うために、昨日まで書いたのです。これはシンプルなテキストフィルタであり、ディレクティブを@synthesizeに拡張する(適切なwhen句をcaseステートメントに追加して、when block_end条件に適切に追加する)、それを拡張して複数の@ 1つのファイルに/ @の実装インタフェース(他のすべてのスクリプトであるとして自分の名前を追跡することによって---それは、正規表現のキャプチャを介して行うことができます):

#! /usr/bin/ruby 

# -------------- Basic Definitions ----------------------------- 

doc = "%%%{PBXFilePath}%%%" 

# regular expressions 

search_exp = /[[:space:]]*([[a-zA-Z0-9]]*)[[:space:]]\*([a-zA-Z0-9]*)/ 
interface_start = /@interface/ 
block_end = /^\}/ 

#initializing variables 

properties_list = [] 
properties_string = "" 
reading_interface = 0 

#---------------- Start Processing ----------------------------- 

file = File.open(doc, "r").readlines 

file.each do |line| 

# capture the regular expression matches only in the 
# interface declaration and print out the matching 
# property declarations 

    case line 

    # start capturing 
    when interface_start 
    reading_interface = 1 
    puts line 

    # capture and keep in properties_list 
    when search_exp 
    if (reading_interface == 1) then 
     data = Regexp.last_match 
     properties_list << data 
    end 
    puts line 

    # unpack properties_list and print out the property 
    # declarations 
    when block_end 
    if (reading_interface == 1) then 
     reading_interface = 0 
     properties_list.each do |pair| 
     properties_string << "@property (readwrite, copy) #{pair[0].lstrip};\n" 
     end 
     puts line 
     puts "\n" + properties_string 
    end 
    else puts line 
    end 

end 

私は「何も入力」を使用していない、これを実行すると「置き換えますUser ScriptsエディタでI/Oのオプションとして「ドキュメントの内容」を選択します。

1

私は現在使用しているユーザースクリプトです - 一度に1つのインスタンス変数で動作します。これは正しい保持メカニズム(単純な型は保持されません)を使用しようとし、実装ファイルに@synthesizeステートメントも作成します。現在、deallocステートメントは作成されていません。

#! /usr/bin/perl -w 

#Input: Selection 
#Directory: Selection 
#Output: Display in Alert 
#Errors: Display in Alert 

use strict; 

# Get the header file contents from Xcode user scripts 
my $headerFileContents = <<'HEADERFILECONTENTS'; 
%%%{PBXAllText}%%% 
HEADERFILECONTENTS 

# Get the indices of the selection from Xcode user scripts 
my $selectionStartIndex = %%%{PBXSelectionStart}%%%; 
my $selectionEndIndex = %%%{PBXSelectionEnd}%%%; 

# Get path of the header file 
my $implementationFilePath = "%%%{PBXFilePath}%%%"; 
my $headerFilePath = $implementationFilePath; 

# Look for an implemenation file with a ".m" or ".mm" extension 
$implementationFilePath =~ s/\.[hm]*$/.m/; 
if (!(-e $implementationFilePath)) 
{ 
    $implementationFilePath =~ s/.m$/.mm/; 
} 

# Handle subroutine to trime whitespace off both ends of a string 
sub trim 
{ 
    my $string = shift; 
    $string =~ s/^\s*(.*?)\s*$/$1/; 
    return $string; 
} 


# Get the selection out of the header file 
my $selectedText = substr $headerFileContents, $selectionStartIndex, ($selectionEndIndex - $selectionStartIndex); 

#my $otherText = substr $headerFileContents, $selectionStartIndex; 
#my $pulledText = ""; 
#if (length($otherText) && $otherText =~ /.*$(^.*;).*/) 
#{ 
# $pulledText = $1; 
#} 
# 
# 
#print $pulledText; 


$selectedText = trim $selectedText; 


my $type = ""; 
my $asterisk = ""; 
my $name = ""; 
my $behavior = ""; 
my $iboutlet = ""; 

# Test that the selection is: 
# At series of identifiers (the type name and access specifiers) 
# Possibly an asterisk 
# Another identifier (the variable name) 
# A semi-colon 
if (length($selectedText) && ($selectedText =~ /([_A-Za-z][_A-Za-z0-9]*\s*)+([\s\*]+)([_A-Za-z][_A-Za-z0-9]*)/)) 
{ 
    $type = $1; 
    $type = trim $type; 
    $asterisk = $2; 
    $asterisk = trim $asterisk; 
    $name = $3; 
    $behavior = ""; 
    if (defined($asterisk) && length($asterisk) == 1) 
    { 
     $behavior = "(nonatomic, retain) "; 
    } 
    else 
    { 
     $behavior = "(nonatomic) "; 
     $asterisk = ""; 
    } 
} 
else 
{ 
    print "Bailing, error in Regex"; 
    exit 1; 
} 

# special case, see if we need to keep around an IBOUTLET declaration. 
if (length($selectedText) && ($selectedText =~ /IBOutlet/)) 
{ 
    $iboutlet = "IBOutlet "; 
} 

# Find the closing brace (end of the class variables section) 
my $remainderOfHeader = substr $headerFileContents, $selectionEndIndex; 
my $indexAfterClosingBrace = $selectionEndIndex + index($remainderOfHeader, "\n}\n") + 3; 
if ($indexAfterClosingBrace == -1) 
{ 
    exit 1; 
} 

# Determine if we need to add a newline in front of the property declaration 
my $leadingNewline = "\n"; 
if (substr($headerFileContents, $indexAfterClosingBrace, 1) eq "\n") 
{ 
    $indexAfterClosingBrace += 1; 
    $leadingNewline = ""; 
} 

# Determine if we need to add a newline after the property declaration 
my $trailingNewline = "\n"; 
if (substr($headerFileContents, $indexAfterClosingBrace, 9) eq "\@property") 
{ 
    $trailingNewline = ""; 
} 

# Create and insert the proper declaration 
my $propertyDeclaration = $leadingNewline . "\@property " . $behavior . $iboutlet . $type . " " . $asterisk . $name . ";\n" . $trailingNewline; 
substr($headerFileContents, $indexAfterClosingBrace, 0) = $propertyDeclaration; 

my $replaceFileContentsScript = <<'REPLACEFILESCRIPT'; 
on run argv 
    set fileAlias to POSIX file (item 1 of argv) 
    set newDocText to (item 2 of argv) 
    tell application "Xcode" 
     set doc to open fileAlias 
     set text of doc to newDocText 
    end tell 
end run 
REPLACEFILESCRIPT 

# Use Applescript to replace the contents of the header file 
# (I could have used the "Output" of the Xcode user script instead) 
system 'osascript', '-e', $replaceFileContentsScript, $headerFilePath, $headerFileContents; 

# Stop now if the implementation file can't be found 
if (!(-e $implementationFilePath)) 
{ 
    exit 1; 
} 

my $getFileContentsScript = <<'GETFILESCRIPT'; 
on run argv 
    set fileAlias to POSIX file (item 1 of argv) 
    tell application "Xcode" 
     set doc to open fileAlias 
     set docText to text of doc 
    end tell 
    return docText 
end run 
GETFILESCRIPT 

# Get the contents of the implmentation file 
open(SCRIPTFILE, '-|') || exec 'osascript', '-e', $getFileContentsScript, $implementationFilePath; 
my $implementationFileContents = do {local $/; <SCRIPTFILE>}; 
close(SCRIPTFILE); 

# Look for the class implementation statement 
if (length($implementationFileContents) && ($implementationFileContents =~ /(\@implementation [_A-Za-z][_A-Za-z0-9]*\n)/)) 
{ 
    my $matchString = $1; 
    my $indexAfterMatch = index($implementationFileContents, $matchString) + length($matchString); 

    # Determine if we want a newline before the synthesize statement 
    $leadingNewline = "\n"; 
    if (substr($implementationFileContents, $indexAfterMatch, 1) eq "\n") 
    { 
     $indexAfterMatch += 1; 
     $leadingNewline = ""; 
    } 

    # Determine if we want a newline after the synthesize statement 
    $trailingNewline = "\n"; 
    if (substr($implementationFileContents, $indexAfterMatch, 11) eq "\@synthesize") 
    { 
     $trailingNewline = ""; 
    } 

    # Create and insert the synthesize statement 
    my $synthesizeStatement = $leadingNewline . "\@synthesize " . $name . ";\n" . $trailingNewline; 
    substr($implementationFileContents, $indexAfterMatch, 0) = $synthesizeStatement; 

    # Use Applescript to replace the contents of the implementation file in Xcode 
    system 'osascript', '-e', $replaceFileContentsScript, $implementationFilePath, $implementationFileContents; 
} 

exit 0; 
0

Accessorizer http://www.kevincallahan.org/software/accessorizer.htmlはこのようなものと、より多くを行います。また、カスタム接頭辞と接尾辞(接尾辞)を処理します。あなたがGoogleのアンダースコアを望むなら、それを手に入れました。変更したい場合は、その場で変更してください。スクリプトを編集する必要はありません。さらに、渡されたivarのタイプ(コピー、保持、読み取り専用、割り当てなど)に基づいて、デフォルトのプロパティ指定子を定義できるデフォルトテーブルがあります。 IBOutletの検出を行い、自動的にIBOutletキーワードを挿入し、-viewDidUnloadのビューを削除し、いくつかのスタイルのdeallocを行います。また、コレクションのすべてのヘアリーアクセサ(NSMutableArrayとNSSet)も書き込みます。これは、キーのアーカイブ、様々なロックのアプローチ、あなたのプロパティをソートし、ブロックを合成することができますKVOコードを書く、シングルトンコード、セレクタに変換、HeaderDocタグ、NSLog()を生成...改行にかっこを入れるかどうか、スペーシングにはカスタム引数名などが必要です。ほとんどのものはServicesで処理されるので、単純にivarブロックを選択し、キーストロークを2回押すだけです。 Accessorizerをドックに最小化すると、インターフェイスが前面に表示されず、Xcodeやサービスをサポートする他のエディタに集中することができます。もちろん、Accessorizerは明示的なアクセサ(Objective-C 1.0のように)を書き出し、プロパティをオーバーライドすることができます。これらはすべてスイッチの単純な切り替えで行います。渡されたタイプに基づいてオーバーライドをカスタマイズすることもできます。動画を見て、実際の動作を確認してください。

2

これは生成のXcode 3.2.4のためのPythonスクリプトです。インタフェースのプロパティ、実装の合成、およびdeallocです。 インストールするには、このスクリプトをコピーし、Xcodeスクリプトメニュー(2番目から最後まで) 「ユーザースクリプトの編集...」 コードの下に追加して、新しいスクリプト名を作成し、以下のpythonスクリプトを貼り付けます。

@interfaceの下の変数を選択するだけでこのスクリプトを呼び出します。 これで、実装の と@synthesizeとdeallocのすべての@プロパティがすべて追加されます。 これは知らないので、IBOutletをラベルやボタンに追加することはありませんが、 は手動で簡単に追加できます。

以下のスクリプトのインデントは重要なので、変更しないでください。

#!/usr/bin/python 


# Takes a header file with one or more instance variables selected 
# and creates properties and synthesize directives for the selected properties. 

# Accepts google-style instance variables with a tailing underscore and 
# creates an appropriately named property without underscore. 

# Xcode script options should be as follows: 
# Entire Document 
# Home Directory 
# Discard Output 
# Display in Alert 

import os 
import re 
import subprocess 

# AppleScripts for altering contents of files via Xcode 
setFileContentsScript = """\ 
on run argv 
set fileAlias to POSIX file (item 1 of argv) 
set newDocText to (item 2 of argv) 
tell application "Xcode" 
set doc to open fileAlias 
set text of doc to newDocText 
end tell 
end run \ 
""" 

getFileContentsScript = """\ 
on run argv 
set fileAlias to POSIX file (item 1 of argv) 
tell application "Xcode" 
set doc to open fileAlias 
set docText to text of doc 
end tell 
return docText 
end run \ 
""" 

# Get variables from Xcode 
headerFileText = """%%%{PBXAllText}%%%""" 
selectionStartIndex = %%%{PBXSelectionStart}%%% 
selectionEndIndex = %%%{PBXSelectionEnd}%%% 
selectedText = headerFileText[selectionStartIndex:selectionEndIndex] 

headerFilePath = """%%%{PBXFilePath}%%%""" 

# Look for an implementation file with .m or .mm extension 
implementationFilePath = headerFilePath[:-1] + "m" 
if not os.path.exists(implementationFilePath): 
implementationFilePath += "m" 

instanceVariablesRegex = re.compile(
"""^\s*((?:(?:\\b\w+\\b)\s+)*(?:(?:\\b\\w+\\b)))\\s*""" + # Identifier(s) 
"""([*]?)\\s*""" + # An optional asterisk 
"""(\\b\\w+?)(_?\\b);""", # The variable name 
re.M) 

# Now for each instance variable in the selected section 
properties = "" 
synthesizes = "" 
deallocs = "" 

for lineMatch in instanceVariablesRegex.findall(selectedText): 
    types = " ".join(lineMatch[0].split()) # Clean up consequtive whitespace 

    asterisk = lineMatch[1] 
    variableName = lineMatch[2] 
    trailingUnderscore = lineMatch[3] 

    pointerPropertyAttributes = "(nonatomic, retain) " # Attributes if variable is pointer 
    if not asterisk: 
     pointerPropertyAttributes = "(nonatomic, assign) " 

    newProperty = "@property %s%s %s%s;\n" % (pointerPropertyAttributes, 
             types, 
             asterisk, 
             variableName) 

    # If there's a trailing underscore, we need to let the synthesize 
    # know which backing variable it's using 
    newSynthesize = "@synthesize %s%s;\n" % (variableName, 
            trailingUnderscore and 
            " = %s_" % variableName) 
    # only do the objects 
    if asterisk: 
     newDealloc = " [%s%s release];\n" % (variableName, 
        trailingUnderscore and 
           " = %s_" % variableName) 
    properties += newProperty 
    synthesizes += newSynthesize 
    # only add if it's an object 
    if asterisk: 
     deallocs += newDealloc 


# Check to make sure at least 1 properties was found to generate 
if not properties: 
    os.sys.stderr.writelines("No properties found to generate") 
    exit(-1) 

# We want to insert the new properties either immediately after the last 
# existing property or at the end of the instance variable section 
findLastPropertyRegex = re.compile("^@interface.*?{.*?}.*?\\n" + 
         "(?:.*^\\s*@property.*?\\n)?", re.M | re.S) 
headerInsertIndex = findLastPropertyRegex.search(headerFileText).end() 

# Add new lines on either side if this is the only property in the file 
addedNewLine = "\n" 
if re.search("^\s*@property", headerFileText, re.M): 
    # Not the only property, don't add 
    addedNewLine = "" 

newHeaderFileText = "%s%s%s%s" % (headerFileText[:headerInsertIndex], 
         addedNewLine, 
         properties, 
         headerFileText[headerInsertIndex:]) 

subprocess.call(["osascript", 
     "-e", 
     setFileContentsScript, 
     headerFilePath, 
     newHeaderFileText]) 


if not os.path.exists(implementationFilePath): 
    os.sys.stdout.writelines("No implementation file found") 
    exit(0) 

implementationFileText = subprocess.Popen(
["osascript", 
"-e", 
getFileContentsScript, 
implementationFilePath], 
stdout=subprocess.PIPE).communicate()[0] 

# We want to insert the synthesizes either immediately after the last existing 
# @synthesize or after the @implementation directive 
lastSynthesizeRegex = re.compile("^\\s*@implementation.*?\\n" + 
         "(?:.*^\\s*@synthesize.*?\\n)?", re.M | re.S) 

implementationInsertIndex = \ 
lastSynthesizeRegex.search(implementationFileText).end() 

# Add new lines on either side if this is the only synthsize in the file 
addedNewLine = "\n" 
if re.search("^\s*@synthesize", implementationFileText, re.M): 
    # Not the only synthesize, don't add 
    addedNewLine = "" 

newImplementationFileText = "%s%s%s%s" % \ 
     (implementationFileText[:implementationInsertIndex], 
     addedNewLine, 
     synthesizes, 
     implementationFileText[implementationInsertIndex:]) 

subprocess.call(["osascript", 
     "-e", 
     setFileContentsScript, 
     implementationFilePath, 
     newImplementationFileText]) 


implementationFileText = subprocess.Popen(
["osascript", 
"-e", 
getFileContentsScript, 
implementationFilePath], 
stdout=subprocess.PIPE).communicate()[0] 

# We want to insert the deallocs either immediately after the last existing 
# [* release] or after the [super dealloc] 
lastDeallocRegex = re.compile("^\\s+\[super dealloc\];?\\n" + 
         "(?:.*^\\s+\[\w release\];?\\n)?", re.M | re.S) 

deallocInsertIndex = \ 
lastDeallocRegex.search(implementationFileText).end() 

addedNewDeallocLine = "\n" 
if re.search("^\s*\[\w release\];?", implementationFileText, re.M): 
# Not the only dealloc, don't add 
addedNewDeallocLine = "" 


newImplementationFileText = "%s%s%s%s" % \ 
     (implementationFileText[:deallocInsertIndex], 
      addedNewDeallocLine, 
      deallocs, 
      implementationFileText[deallocInsertIndex:]) 

subprocess.call(["osascript", 
       "-e", 
       setFileContentsScript, 
       implementationFilePath, 
       newImplementationFileText])  

# Switch Xcode back to header file 
subprocess.Popen(["osascript", 
     "-e", 
     getFileContentsScript, 
     headerFilePath], 
     stdout=subprocess.PIPE).communicate() 
1

おっと、ここには狂ったスクリプトがたくさんあります。 Xcodeの4.4のよう

(多分前)...あなたのIVAR sが例えば...自動合成されるであろう。..

@property (assign) BOOL automatically; 
@property (strong) NSArray *believeDat; 

は "accessored" することができ

self.automatically = YES; 

を経由し、次のような先頭に自動生成されたアンダースコアを使用してインスタンス変数を直接編集します。

_believeDat = @["thank you, jesus", @"mary poopins"]; 

いいえ@synthesizeが必要です。

@property ...次のコードを「コードスニペット」ライブラリに一度にドラッグしてください。キーボードショートカットを割り当てて、これらのジャンプオフポイントを挿入してプロパティをより迅速に作成できます。私は、オブジェクトとプリミティブのAAAためRRRを使用..しかしthatsの私だけ...

@property (nonatomic, assign) <#type#> <#name#>;

@property (nonatomic, retain) <#type#> *<#name#>;

少なくとも最後のではなく、といくつかのクレイジー私を呼び出すことができます。..しかし、私は.pchに次のマクロを投げ込み、さらに迅速化し、明確にし、プロセスを歓迎します。

アップルのクラスのための同様の構造 #define S( #define NSA NSArray \ #define NSS NSString)と一緒に
#define RONLY readonly 
#define RDWRT readwrite 
#define NATOM nonatomic 
#define STRNG strong 
#define ASS assign 
#define CP copy 
#define SET setter 
#define GET getter 

が、これは、...のように見て、(私にとっては)

@property (NATOM, STRNG) NSA* fonts; 
@property (NATOM, STRNG) NSS* cachedPath; 
+0

つまり、すべての@propertyが自動的に合成されるということですか?合成を定義する必要はありませんか? – Dejell

関連する問題